Merge branch 'dev' into device_visualization

This commit is contained in:
Xuwznln
2025-06-12 20:57:16 +08:00
committed by GitHub
11 changed files with 47 additions and 33 deletions

View File

@@ -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.3-xxxxx.tar.bz2
conda install ros-humble-unilabos-msgs-0.9.4-xxxxx.tar.bz2
# Install PyLabRobot and other prerequisites
git clone https://github.com/PyLabRobot/pylabrobot plr_repo

View File

@@ -49,7 +49,7 @@ conda env update --file unilabos-[YOUR_OS].yml -n 环境名
# 现阶段,需要安装 `unilabos_msgs` 包
# 可以前往 Release 页面下载系统对应的包进行安装
conda install ros-humble-unilabos-msgs-0.9.3-xxxxx.tar.bz2
conda install ros-humble-unilabos-msgs-0.9.4-xxxxx.tar.bz2
# 安装PyLabRobot等前置
git clone https://github.com/PyLabRobot/pylabrobot plr_repo

View File

@@ -1,6 +1,6 @@
package:
name: ros-humble-unilabos-msgs
version: 0.9.3
version: 0.9.4
source:
path: ../../unilabos_msgs
folder: ros-humble-unilabos-msgs/src/work

View File

@@ -1,6 +1,6 @@
package:
name: unilabos
version: "0.9.3"
version: "0.9.4"
source:
path: ../..

View File

@@ -4,7 +4,7 @@ package_name = 'unilabos'
setup(
name=package_name,
version='0.9.3',
version='0.9.4',
packages=find_packages(),
include_package_data=True,
install_requires=['setuptools'],

View File

@@ -576,7 +576,7 @@ Window Geometry:
Hide Left Dock: false
Hide Right Dock: true
MotionPlanning:
collapsed: false
collapsed: true
MotionPlanning - Trajectory Slider:
collapsed: false
QMainWindow State: 000000ff00000000fd0000000400000000000003a30000079bfc020000000bfb0000001200530065006c0065006300740069006f006e00000001e10000009b000000b000fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c0061007900730100000027000004c60000018200fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb000000280020002d0020005400720061006a006500630074006f0072007900200053006c00690064006500720000000000ffffffff0000000000000000fb00000044004d006f00740069006f006e0050006c0061006e006e0069006e00670020002d0020005400720061006a006500630074006f0072007900200053006c00690064006500720000000000ffffffff0000007a00fffffffb0000001c004d006f00740069006f006e0050006c0061006e006e0069006e006701000004f9000002c9000002b800ffffff000000010000010f00000387fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073000000003b000003870000013200fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004420000003efc0100000002fb0000000800540069006d00650100000000000004420000000000000000fb0000000800540069006d0065010000000000000450000000000000000000000bc50000079b00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730000000000ffffffff0000000000000000

View File

@@ -5,6 +5,6 @@ io_snrd:
type: python
hardware_interface:
name: modbus_client
extra_info: address
extra_info: []
read: read_io_coil
write: write_io_coil

View File

@@ -343,8 +343,8 @@ class BaseROS2DeviceNode(Node, Generic[T]):
ADD_LIQUID_TYPE = other_calling_param.pop("ADD_LIQUID_TYPE", [])
LIQUID_VOLUME = other_calling_param.pop("LIQUID_VOLUME", [])
LIQUID_INPUT_SLOT = other_calling_param.pop("LIQUID_INPUT_SLOT", [])
slot = other_calling_param.pop("slot", -1)
if slot >= 0: # slot为负数的时候采用assign方法
slot = other_calling_param.pop("slot", "-1")
if slot != "-1": # slot为负数的时候采用assign方法
other_calling_param["slot"] = slot
# 本地拿到这个物料,可能需要先做初始化?
if isinstance(resources, list):
@@ -368,16 +368,21 @@ class BaseROS2DeviceNode(Node, Generic[T]):
# 如果driver自己就有assign的方法那就使用driver自己的assign方法
if hasattr(self.driver_instance, "create_resource"):
create_resource_func = getattr(self.driver_instance, "create_resource")
create_resource_func(
resource_tracker=self.resource_tracker,
resources=request.resources,
bind_parent_id=bind_parent_id,
bind_location=location,
liquid_input_slot=LIQUID_INPUT_SLOT,
liquid_type=ADD_LIQUID_TYPE,
liquid_volume=LIQUID_VOLUME,
slot_on_deck=slot,
)
try:
ret = create_resource_func(
resource_tracker=self.resource_tracker,
resources=request.resources,
bind_parent_id=bind_parent_id,
bind_location=location,
liquid_input_slot=LIQUID_INPUT_SLOT,
liquid_type=ADD_LIQUID_TYPE,
liquid_volume=LIQUID_VOLUME,
slot_on_deck=slot,
)
res.response = serialize_result_info("", True, ret)
except Exception as e:
traceback.print_exc()
res.response = serialize_result_info(traceback.format_exc(), False, {})
return res
# 接下来该根据bind_parent_id进行assign了目前只有plr可以进行assign不然没有办法输入到物料系统中
resource = self.resource_tracker.figure_resource({"name": bind_parent_id})
@@ -403,9 +408,10 @@ class BaseROS2DeviceNode(Node, Generic[T]):
empty_liquid_info_in[liquid_input_slot] = (liquid_type, liquid_volume)
plr_instance.set_well_liquids(empty_liquid_info_in)
if isinstance(resource, OTDeck) and "slot" in other_calling_param:
other_calling_param["slot"] = int(other_calling_param["slot"])
resource.assign_child_at_slot(plr_instance, **other_calling_param)
else:
_discard_slot = other_calling_param.pop("slot", -1)
_discard_slot = other_calling_param.pop("slot", "-1")
resource.assign_child_resource(
plr_instance,
Coordinate(location["x"], location["y"], location["z"]),

View File

@@ -342,6 +342,7 @@ class HostNode(BaseROS2DeviceNode):
bind_locations: list[Point],
other_calling_params: list[str],
):
responses = []
for resource, device_id, bind_parent_id, bind_location, other_calling_param in zip(
resources, device_ids, bind_parent_ids, bind_locations, other_calling_params
):
@@ -367,8 +368,8 @@ class HostNode(BaseROS2DeviceNode):
ensure_ascii=False,
)
response = sclient.call(request)
pass
pass
responses.append(response)
return responses
def create_resource(
self,
@@ -380,7 +381,7 @@ class HostNode(BaseROS2DeviceNode):
liquid_input_slot: list[int],
liquid_type: list[str],
liquid_volume: list[int],
slot_on_deck: int,
slot_on_deck: str,
):
init_new_res = initialize_resource(
{

View File

@@ -1,6 +1,7 @@
import time
import asyncio
import traceback
from types import MethodType
from typing import Union
import rclpy
@@ -87,7 +88,10 @@ class ROS2ProtocolNode(BaseROS2DeviceNode):
# 如果硬件接口是字符串,通过通信设备提供
if isinstance(name, str) and name in self.sub_devices:
communicate_device = self.sub_devices[name]
communicate_hardware_info = communicate_device.ros_node_instance._hardware_interface
self._setup_hardware_proxy(d, self.sub_devices[name], read, write)
self.lab_logger().info(f"\n通信代理:为子设备{device_id}\n 添加了{read}方法(来源:{name} {communicate_hardware_info['write']}) \n 添加了{write}方法(来源:{name} {communicate_hardware_info['read']})")
def _setup_protocol_names(self, protocol_type):
# 处理协议类型
@@ -241,20 +245,23 @@ class ROS2ProtocolNode(BaseROS2DeviceNode):
def _setup_hardware_proxy(self, device: ROS2DeviceNode, communication_device: ROS2DeviceNode, read_method, write_method):
"""为设备设置硬件接口代理"""
extra_info = [getattr(device.driver_instance, info) for info in communication_device.ros_node_instance._hardware_interface.get("extra_info", [])]
write_func = getattr(communication_device.ros_node_instance, communication_device.ros_node_instance._hardware_interface["write"])
read_func = getattr(communication_device.ros_node_instance, communication_device.ros_node_instance._hardware_interface["read"])
# extra_info = [getattr(device.driver_instance, info) for info in communication_device.ros_node_instance._hardware_interface.get("extra_info", [])]
write_func = getattr(communication_device.driver_instance, communication_device.ros_node_instance._hardware_interface["write"])
read_func = getattr(communication_device.driver_instance, communication_device.ros_node_instance._hardware_interface["read"])
def _read():
return read_func(*extra_info)
def _read(*args, **kwargs):
return read_func(*args, **kwargs)
def _write(command):
return write_func(*extra_info, command)
def _write(*args, **kwargs):
return write_func(*args, **kwargs)
if read_method:
setattr(device.driver_instance, read_method, _read)
bound_read = MethodType(_read, device.driver_instance)
setattr(device.driver_instance, read_method, bound_read)
if write_method:
setattr(device.driver_instance, write_method, _write)
bound_write = MethodType(_write, device.driver_instance)
setattr(device.driver_instance, write_method, bound_write)
async def _update_resources(self, goal, protocol_kwargs):

View File

@@ -6,7 +6,7 @@ geometry_msgs/Point bind_locations
int32[] liquid_input_slot
string[] liquid_type
float32[] liquid_volume
int32 slot_on_deck
string slot_on_deck
---
string return_info
bool success