mirror of
https://github.com/dptech-corp/Uni-Lab-OS.git
synced 2026-02-06 06:25:06 +00:00
create container
This commit is contained in:
@@ -3,3 +3,9 @@
|
|||||||
```bash
|
```bash
|
||||||
ros2 action send_goal /devices/host_node/create_resource_detailed unilabos_msgs/action/_resource_create_from_outer/ResourceCreateFromOuter "{ resources: [ { 'category': '', 'children': [], 'config': { 'type': 'Well', 'size_x': 6.86, 'size_y': 6.86, 'size_z': 10.67, 'rotation': { 'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation' }, 'category': 'well', 'model': null, 'max_volume': 360, 'material_z_thickness': 0.5, 'compute_volume_from_height': null, 'compute_height_from_volume': null, 'bottom_type': 'flat', 'cross_section_type': 'circle' }, 'data': { 'liquids': [], 'pending_liquids': [], 'liquid_history': [] }, 'id': 'plate_well_11_7', 'name': 'plate_well_11_7', 'pose': { 'orientation': { 'w': 1.0, 'x': 0.0, 'y': 0.0, 'z': 0.0 }, 'position': { 'x': 0.0, 'y': 0.0, 'z': 0.0 } }, 'sample_id': '', 'parent': 'plate', 'type': 'device' } ], device_ids: [ 'PLR_STATION' ], bind_parent_ids: [ 'plate' ], bind_locations: [ { 'x': 0.0, 'y': 0.0, 'z': 0.0 } ], other_calling_params: [ '{}' ] }"
|
ros2 action send_goal /devices/host_node/create_resource_detailed unilabos_msgs/action/_resource_create_from_outer/ResourceCreateFromOuter "{ resources: [ { 'category': '', 'children': [], 'config': { 'type': 'Well', 'size_x': 6.86, 'size_y': 6.86, 'size_z': 10.67, 'rotation': { 'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation' }, 'category': 'well', 'model': null, 'max_volume': 360, 'material_z_thickness': 0.5, 'compute_volume_from_height': null, 'compute_height_from_volume': null, 'bottom_type': 'flat', 'cross_section_type': 'circle' }, 'data': { 'liquids': [], 'pending_liquids': [], 'liquid_history': [] }, 'id': 'plate_well_11_7', 'name': 'plate_well_11_7', 'pose': { 'orientation': { 'w': 1.0, 'x': 0.0, 'y': 0.0, 'z': 0.0 }, 'position': { 'x': 0.0, 'y': 0.0, 'z': 0.0 } }, 'sample_id': '', 'parent': 'plate', 'type': 'device' } ], device_ids: [ 'PLR_STATION' ], bind_parent_ids: [ 'plate' ], bind_locations: [ { 'x': 0.0, 'y': 0.0, 'z': 0.0 } ], other_calling_params: [ '{}' ] }"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
使用mock_all.json启动,重新捕获MockContainerForChiller1
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ros2 action send_goal /devices/host_node/create_resource unilabos_msgs/action/_resource_create_from_outer_easy/ResourceCreateFromOuterEasy "{ 'res_id': 'MockContainerForChiller1', 'device_id': 'MockChiller1', 'class_name': 'container', 'parent': 'MockChiller1', 'bind_locations': { 'x': 0.0, 'y': 0.0, 'z': 0.0 }, 'liquid_input_slot': [ -1 ], 'liquid_type': [ 'CuCl2' ], 'liquid_volume': [ 100.0 ], 'slot_on_deck': '' }"
|
||||||
|
```
|
||||||
@@ -3,7 +3,9 @@
|
|||||||
{
|
{
|
||||||
"id": "MockChiller1",
|
"id": "MockChiller1",
|
||||||
"name": "模拟冷却器",
|
"name": "模拟冷却器",
|
||||||
"children": [],
|
"children": [
|
||||||
|
|
||||||
|
],
|
||||||
"parent": null,
|
"parent": null,
|
||||||
"type": "device",
|
"type": "device",
|
||||||
"class": "mock_chiller",
|
"class": "mock_chiller",
|
||||||
@@ -25,6 +27,22 @@
|
|||||||
"purpose": ""
|
"purpose": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "MockContainerForChiller1",
|
||||||
|
"name": "模拟容器",
|
||||||
|
"type": "container",
|
||||||
|
"parent": "MockChiller1",
|
||||||
|
"position": {
|
||||||
|
"x": 5,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"liquid_type": "CuCl2",
|
||||||
|
"liquid_volume": "100"
|
||||||
|
},
|
||||||
|
"children": []
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "MockFilter1",
|
"id": "MockFilter1",
|
||||||
"name": "模拟过滤器",
|
"name": "模拟过滤器",
|
||||||
|
|||||||
5
unilabos/registry/resources/opentrons/container.yaml
Normal file
5
unilabos/registry/resources/opentrons/container.yaml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
container:
|
||||||
|
description: regular organic container
|
||||||
|
class:
|
||||||
|
module: unilabos.resources.container:RegularContainer
|
||||||
|
type: unilabos
|
||||||
61
unilabos/resources/container.py
Normal file
61
unilabos/resources/container.py
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
from unilabos_msgs.msg import Resource
|
||||||
|
|
||||||
|
from unilabos.ros.msgs.message_converter import convert_from_ros_msg
|
||||||
|
|
||||||
|
|
||||||
|
class RegularContainer(object):
|
||||||
|
# 第一个参数必须是id传入
|
||||||
|
# noinspection PyShadowingBuiltins
|
||||||
|
def __init__(self, id: str, data: dict = None):
|
||||||
|
self.id = id
|
||||||
|
self.ulr_resource = Resource()
|
||||||
|
self.ulr_resource_data = data
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ulr_resource_data(self):
|
||||||
|
return json.loads(self.ulr_resource.data) if self.ulr_resource.data else {}
|
||||||
|
|
||||||
|
@ulr_resource_data.setter
|
||||||
|
def ulr_resource_data(self, value: dict):
|
||||||
|
self.ulr_resource.data = json.dumps(value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def liquid_type(self):
|
||||||
|
return self.ulr_resource_data.get("liquid_type", None)
|
||||||
|
|
||||||
|
@liquid_type.setter
|
||||||
|
def liquid_type(self, value: str):
|
||||||
|
if value is not None:
|
||||||
|
self.ulr_resource_data["liquid_type"] = value
|
||||||
|
else:
|
||||||
|
self.ulr_resource_data.pop("liquid_type", None)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def liquid_volume(self):
|
||||||
|
return self.ulr_resource_data.get("liquid_volume", None)
|
||||||
|
|
||||||
|
@liquid_volume.setter
|
||||||
|
def liquid_volume(self, value: float):
|
||||||
|
if value is not None:
|
||||||
|
self.ulr_resource_data["liquid_volume"] = value
|
||||||
|
else:
|
||||||
|
self.ulr_resource_data.pop("liquid_volume", None)
|
||||||
|
|
||||||
|
def get_ulr_resource(self) -> Resource:
|
||||||
|
"""
|
||||||
|
获取UlrResource对象
|
||||||
|
:return: UlrResource对象
|
||||||
|
"""
|
||||||
|
return self.ulr_resource
|
||||||
|
|
||||||
|
def get_ulr_resource_as_dict(self) -> Resource:
|
||||||
|
"""
|
||||||
|
获取UlrResource对象
|
||||||
|
:return: UlrResource对象
|
||||||
|
"""
|
||||||
|
return convert_from_ros_msg(self.ulr_resource)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.id}"
|
||||||
@@ -5,6 +5,8 @@ from typing import Union
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import networkx as nx
|
import networkx as nx
|
||||||
|
|
||||||
|
from unilabos.resources.container import RegularContainer
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from pylabrobot.resources.resource import Resource as ResourcePLR
|
from pylabrobot.resources.resource import Resource as ResourcePLR
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@@ -466,6 +468,9 @@ def initialize_resource(resource_config: dict) -> list[dict]:
|
|||||||
if resource_config.get("position") is not None:
|
if resource_config.get("position") is not None:
|
||||||
r["position"] = resource_config["position"]
|
r["position"] = resource_config["position"]
|
||||||
r = tree_to_list([r])
|
r = tree_to_list([r])
|
||||||
|
elif resource_class_config["type"] == "unilabos":
|
||||||
|
res_instance: RegularContainer = RESOURCE(id=resource_config["name"], data=resource_config.get("data", {}))
|
||||||
|
r = [res_instance.get_ulr_resource_as_dict()]
|
||||||
elif isinstance(RESOURCE, dict):
|
elif isinstance(RESOURCE, dict):
|
||||||
r = [RESOURCE.copy()]
|
r = [RESOURCE.copy()]
|
||||||
|
|
||||||
|
|||||||
@@ -343,6 +343,8 @@ class BaseROS2DeviceNode(Node, Generic[T]):
|
|||||||
ADD_LIQUID_TYPE = other_calling_param.pop("ADD_LIQUID_TYPE", [])
|
ADD_LIQUID_TYPE = other_calling_param.pop("ADD_LIQUID_TYPE", [])
|
||||||
LIQUID_VOLUME = other_calling_param.pop("LIQUID_VOLUME", [])
|
LIQUID_VOLUME = other_calling_param.pop("LIQUID_VOLUME", [])
|
||||||
LIQUID_INPUT_SLOT = other_calling_param.pop("LIQUID_INPUT_SLOT", [])
|
LIQUID_INPUT_SLOT = other_calling_param.pop("LIQUID_INPUT_SLOT", [])
|
||||||
|
if len(LIQUID_INPUT_SLOT) and LIQUID_INPUT_SLOT[0] == -1:
|
||||||
|
print("create container")
|
||||||
slot = other_calling_param.pop("slot", "-1")
|
slot = other_calling_param.pop("slot", "-1")
|
||||||
if slot != "-1": # slot为负数的时候采用assign方法
|
if slot != "-1": # slot为负数的时候采用assign方法
|
||||||
other_calling_param["slot"] = slot
|
other_calling_param["slot"] = slot
|
||||||
|
|||||||
@@ -383,18 +383,24 @@ class HostNode(BaseROS2DeviceNode):
|
|||||||
liquid_volume: list[int],
|
liquid_volume: list[int],
|
||||||
slot_on_deck: str,
|
slot_on_deck: str,
|
||||||
):
|
):
|
||||||
init_new_res = initialize_resource(
|
res_creation_input = {
|
||||||
{
|
"name": res_id,
|
||||||
"name": res_id,
|
"class": class_name,
|
||||||
"class": class_name,
|
"parent": parent,
|
||||||
"parent": parent,
|
"position": {
|
||||||
"position": {
|
"x": bind_locations.x,
|
||||||
"x": bind_locations.x,
|
"y": bind_locations.y,
|
||||||
"y": bind_locations.y,
|
"z": bind_locations.z,
|
||||||
"z": bind_locations.z,
|
},
|
||||||
},
|
}
|
||||||
}
|
if len(liquid_input_slot) and liquid_input_slot[0] == -1: # 目前container只逐个创建
|
||||||
) # flatten的格式
|
res_creation_input.update({
|
||||||
|
"data": {
|
||||||
|
"liquid_type": liquid_type[0] if liquid_type else None,
|
||||||
|
"liquid_volume": liquid_volume[0] if liquid_volume else None,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
init_new_res = initialize_resource(res_creation_input) # flatten的格式
|
||||||
resources = init_new_res # initialize_resource已经返回list[dict]
|
resources = init_new_res # initialize_resource已经返回list[dict]
|
||||||
device_ids = [device_id]
|
device_ids = [device_id]
|
||||||
bind_parent_id = [parent]
|
bind_parent_id = [parent]
|
||||||
|
|||||||
Reference in New Issue
Block a user