diff --git a/.gitignore b/.gitignore
index e2c2063..f915811 100644
--- a/.gitignore
+++ b/.gitignore
@@ -232,4 +232,5 @@ CATKIN_IGNORE
/**/local_config.py
-*.graphml
\ No newline at end of file
+*.graphml
+unilabos/device_mesh/view_robot.rviz
diff --git a/README.md b/README.md
index 50380d8..4345f6d 100644
--- a/README.md
+++ b/README.md
@@ -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.2-xxxxx.tar.bz2
+conda install ros-humble-unilabos-msgs-0.9.3-xxxxx.tar.bz2
# Install PyLabRobot and other prerequisites
git clone https://github.com/PyLabRobot/pylabrobot plr_repo
diff --git a/README_zh.md b/README_zh.md
index 2a82b43..5a84b51 100644
--- a/README_zh.md
+++ b/README_zh.md
@@ -49,7 +49,7 @@ conda env update --file unilabos-[YOUR_OS].yml -n 环境名
# 现阶段,需要安装 `unilabos_msgs` 包
# 可以前往 Release 页面下载系统对应的包进行安装
-conda install ros-humble-unilabos-msgs-0.9.2-xxxxx.tar.bz2
+conda install ros-humble-unilabos-msgs-0.9.3-xxxxx.tar.bz2
# 安装PyLabRobot等前置
git clone https://github.com/PyLabRobot/pylabrobot plr_repo
diff --git a/recipes/ros-humble-unilabos-msgs/recipe.yaml b/recipes/ros-humble-unilabos-msgs/recipe.yaml
index a7faf4c..b39e6cd 100644
--- a/recipes/ros-humble-unilabos-msgs/recipe.yaml
+++ b/recipes/ros-humble-unilabos-msgs/recipe.yaml
@@ -1,6 +1,6 @@
package:
name: ros-humble-unilabos-msgs
- version: 0.9.2
+ version: 0.9.3
source:
path: ../../unilabos_msgs
folder: ros-humble-unilabos-msgs/src/work
diff --git a/recipes/unilabos/recipe.yaml b/recipes/unilabos/recipe.yaml
index b261d16..1aea514 100644
--- a/recipes/unilabos/recipe.yaml
+++ b/recipes/unilabos/recipe.yaml
@@ -1,6 +1,6 @@
package:
name: unilabos
- version: "0.9.2"
+ version: "0.9.3"
source:
path: ../..
diff --git a/setup.cfg b/setup.cfg
index e152926..5197889 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,4 +1,2 @@
-[develop]
-script_dir=$base/lib/unilabos
[install]
install_scripts=$base/lib/unilabos
diff --git a/setup.py b/setup.py
index e3a86cd..6a57457 100644
--- a/setup.py
+++ b/setup.py
@@ -4,7 +4,7 @@ package_name = 'unilabos'
setup(
name=package_name,
- version='0.9.2',
+ version='0.9.3',
packages=find_packages(),
include_package_data=True,
install_requires=['setuptools'],
diff --git a/test/experiments/plr_test_converted.json b/test/experiments/plr_test_converted.json
index 533d99c..00f778b 100644
--- a/test/experiments/plr_test_converted.json
+++ b/test/experiments/plr_test_converted.json
@@ -47,6 +47,9 @@
},
"config": {
"type": "OTDeck",
+ "size_x": 624.3,
+ "size_y": 565.2,
+ "size_z": 900,
"with_trash": false,
"rotation": {
"x": 0,
@@ -163,7 +166,7 @@
"type": "plate",
"class": "opentrons_96_filtertiprack_1000ul",
"position": {
- "x": 0,
+ "x": 265.0,
"y": 0,
"z": 69
},
@@ -281,6 +284,10 @@
},
"data": {}
},
+
+
+
+
{
"id": "tip_rack_A1",
"name": "tip_rack_A1",
@@ -290,14 +297,14 @@
"type": "device",
"class": "",
"position": {
- "x": 7.2,
- "y": 68.3,
+ "x": 11.804,
+ "y": 71.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -309,19 +316,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -330,10 +337,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -346,14 +353,14 @@
"type": "device",
"class": "",
"position": {
- "x": 7.2,
- "y": 59.3,
+ "x": 11.804,
+ "y": 62.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -365,19 +372,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -386,10 +393,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -402,14 +409,14 @@
"type": "device",
"class": "",
"position": {
- "x": 7.2,
- "y": 50.3,
+ "x": 11.804,
+ "y": 53.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -421,19 +428,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -442,10 +449,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -458,14 +465,14 @@
"type": "device",
"class": "",
"position": {
- "x": 7.2,
- "y": 41.3,
+ "x": 11.804,
+ "y": 44.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -477,19 +484,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -498,10 +505,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -514,14 +521,14 @@
"type": "device",
"class": "",
"position": {
- "x": 7.2,
- "y": 32.3,
+ "x": 11.804,
+ "y": 35.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -533,19 +540,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -554,10 +561,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -570,14 +577,14 @@
"type": "device",
"class": "",
"position": {
- "x": 7.2,
- "y": 23.3,
+ "x": 11.804,
+ "y": 26.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -589,19 +596,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -610,10 +617,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -626,14 +633,14 @@
"type": "device",
"class": "",
"position": {
- "x": 7.2,
- "y": 14.3,
+ "x": 11.804,
+ "y": 17.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -645,19 +652,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -666,10 +673,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -682,14 +689,14 @@
"type": "device",
"class": "",
"position": {
- "x": 7.2,
- "y": 5.3,
+ "x": 11.804,
+ "y": 8.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -701,19 +708,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -722,10 +729,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -738,14 +745,14 @@
"type": "device",
"class": "",
"position": {
- "x": 16.2,
- "y": 68.3,
+ "x": 20.804,
+ "y": 71.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -757,19 +764,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -778,10 +785,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -794,14 +801,14 @@
"type": "device",
"class": "",
"position": {
- "x": 16.2,
- "y": 59.3,
+ "x": 20.804,
+ "y": 62.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -813,19 +820,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -834,10 +841,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -850,14 +857,14 @@
"type": "device",
"class": "",
"position": {
- "x": 16.2,
- "y": 50.3,
+ "x": 20.804,
+ "y": 53.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -869,19 +876,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -890,10 +897,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -906,14 +913,14 @@
"type": "device",
"class": "",
"position": {
- "x": 16.2,
- "y": 41.3,
+ "x": 20.804,
+ "y": 44.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -925,19 +932,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -946,10 +953,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -962,14 +969,14 @@
"type": "device",
"class": "",
"position": {
- "x": 16.2,
- "y": 32.3,
+ "x": 20.804,
+ "y": 35.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -981,19 +988,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -1002,10 +1009,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -1018,14 +1025,14 @@
"type": "device",
"class": "",
"position": {
- "x": 16.2,
- "y": 23.3,
+ "x": 20.804,
+ "y": 26.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -1037,19 +1044,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -1058,10 +1065,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -1074,14 +1081,14 @@
"type": "device",
"class": "",
"position": {
- "x": 16.2,
- "y": 14.3,
+ "x": 20.804,
+ "y": 17.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -1093,19 +1100,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -1114,10 +1121,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -1130,14 +1137,14 @@
"type": "device",
"class": "",
"position": {
- "x": 16.2,
- "y": 5.3,
+ "x": 20.804,
+ "y": 8.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -1149,19 +1156,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -1170,10 +1177,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -1186,14 +1193,14 @@
"type": "device",
"class": "",
"position": {
- "x": 25.2,
- "y": 68.3,
+ "x": 29.804,
+ "y": 71.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -1205,19 +1212,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -1226,10 +1233,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -1242,14 +1249,14 @@
"type": "device",
"class": "",
"position": {
- "x": 25.2,
- "y": 59.3,
+ "x": 29.804,
+ "y": 62.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -1261,19 +1268,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -1282,10 +1289,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -1298,14 +1305,14 @@
"type": "device",
"class": "",
"position": {
- "x": 25.2,
- "y": 50.3,
+ "x": 29.804,
+ "y": 53.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -1317,19 +1324,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -1338,10 +1345,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -1354,14 +1361,14 @@
"type": "device",
"class": "",
"position": {
- "x": 25.2,
- "y": 41.3,
+ "x": 29.804,
+ "y": 44.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -1373,19 +1380,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -1394,10 +1401,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -1410,14 +1417,14 @@
"type": "device",
"class": "",
"position": {
- "x": 25.2,
- "y": 32.3,
+ "x": 29.804,
+ "y": 35.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -1429,19 +1436,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -1450,10 +1457,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -1466,14 +1473,14 @@
"type": "device",
"class": "",
"position": {
- "x": 25.2,
- "y": 23.3,
+ "x": 29.804,
+ "y": 26.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -1485,19 +1492,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -1506,10 +1513,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -1522,14 +1529,14 @@
"type": "device",
"class": "",
"position": {
- "x": 25.2,
- "y": 14.3,
+ "x": 29.804,
+ "y": 17.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -1541,19 +1548,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -1562,10 +1569,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -1578,14 +1585,14 @@
"type": "device",
"class": "",
"position": {
- "x": 25.2,
- "y": 5.3,
+ "x": 29.804,
+ "y": 8.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -1597,19 +1604,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -1618,10 +1625,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -1634,14 +1641,14 @@
"type": "device",
"class": "",
"position": {
- "x": 34.2,
- "y": 68.3,
+ "x": 38.804,
+ "y": 71.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -1653,19 +1660,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -1674,10 +1681,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -1690,14 +1697,14 @@
"type": "device",
"class": "",
"position": {
- "x": 34.2,
- "y": 59.3,
+ "x": 38.804,
+ "y": 62.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -1709,19 +1716,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -1730,10 +1737,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -1746,14 +1753,14 @@
"type": "device",
"class": "",
"position": {
- "x": 34.2,
- "y": 50.3,
+ "x": 38.804,
+ "y": 53.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -1765,19 +1772,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -1786,10 +1793,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -1802,14 +1809,14 @@
"type": "device",
"class": "",
"position": {
- "x": 34.2,
- "y": 41.3,
+ "x": 38.804,
+ "y": 44.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -1821,19 +1828,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -1842,10 +1849,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -1858,14 +1865,14 @@
"type": "device",
"class": "",
"position": {
- "x": 34.2,
- "y": 32.3,
+ "x": 38.804,
+ "y": 35.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -1877,19 +1884,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -1898,10 +1905,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -1914,14 +1921,14 @@
"type": "device",
"class": "",
"position": {
- "x": 34.2,
- "y": 23.3,
+ "x": 38.804,
+ "y": 26.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -1933,19 +1940,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -1954,10 +1961,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -1970,14 +1977,14 @@
"type": "device",
"class": "",
"position": {
- "x": 34.2,
- "y": 14.3,
+ "x": 38.804,
+ "y": 17.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -1989,19 +1996,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -2010,10 +2017,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -2026,14 +2033,14 @@
"type": "device",
"class": "",
"position": {
- "x": 34.2,
- "y": 5.3,
+ "x": 38.804,
+ "y": 8.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -2045,19 +2052,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -2066,10 +2073,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -2082,14 +2089,14 @@
"type": "device",
"class": "",
"position": {
- "x": 43.2,
- "y": 68.3,
+ "x": 47.804,
+ "y": 71.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -2101,19 +2108,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -2122,10 +2129,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -2138,14 +2145,14 @@
"type": "device",
"class": "",
"position": {
- "x": 43.2,
- "y": 59.3,
+ "x": 47.804,
+ "y": 62.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -2157,19 +2164,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -2178,10 +2185,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -2194,14 +2201,14 @@
"type": "device",
"class": "",
"position": {
- "x": 43.2,
- "y": 50.3,
+ "x": 47.804,
+ "y": 53.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -2213,19 +2220,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -2234,10 +2241,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -2250,14 +2257,14 @@
"type": "device",
"class": "",
"position": {
- "x": 43.2,
- "y": 41.3,
+ "x": 47.804,
+ "y": 44.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -2269,19 +2276,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -2290,10 +2297,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -2306,14 +2313,14 @@
"type": "device",
"class": "",
"position": {
- "x": 43.2,
- "y": 32.3,
+ "x": 47.804,
+ "y": 35.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -2325,19 +2332,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -2346,10 +2353,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -2362,14 +2369,14 @@
"type": "device",
"class": "",
"position": {
- "x": 43.2,
- "y": 23.3,
+ "x": 47.804,
+ "y": 26.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -2381,19 +2388,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -2402,10 +2409,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -2418,14 +2425,14 @@
"type": "device",
"class": "",
"position": {
- "x": 43.2,
- "y": 14.3,
+ "x": 47.804,
+ "y": 17.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -2437,19 +2444,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -2458,10 +2465,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -2474,14 +2481,14 @@
"type": "device",
"class": "",
"position": {
- "x": 43.2,
- "y": 5.3,
+ "x": 47.804,
+ "y": 8.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -2493,19 +2500,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -2514,10 +2521,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -2530,14 +2537,14 @@
"type": "device",
"class": "",
"position": {
- "x": 52.2,
- "y": 68.3,
+ "x": 56.804,
+ "y": 71.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -2549,19 +2556,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -2570,10 +2577,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -2586,14 +2593,14 @@
"type": "device",
"class": "",
"position": {
- "x": 52.2,
- "y": 59.3,
+ "x": 56.804,
+ "y": 62.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -2605,19 +2612,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -2626,10 +2633,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -2642,14 +2649,14 @@
"type": "device",
"class": "",
"position": {
- "x": 52.2,
- "y": 50.3,
+ "x": 56.804,
+ "y": 53.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -2661,19 +2668,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -2682,10 +2689,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -2698,14 +2705,14 @@
"type": "device",
"class": "",
"position": {
- "x": 52.2,
- "y": 41.3,
+ "x": 56.804,
+ "y": 44.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -2717,19 +2724,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -2738,10 +2745,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -2754,14 +2761,14 @@
"type": "device",
"class": "",
"position": {
- "x": 52.2,
- "y": 32.3,
+ "x": 56.804,
+ "y": 35.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -2773,19 +2780,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -2794,10 +2801,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -2810,14 +2817,14 @@
"type": "device",
"class": "",
"position": {
- "x": 52.2,
- "y": 23.3,
+ "x": 56.804,
+ "y": 26.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -2829,19 +2836,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -2850,10 +2857,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -2866,14 +2873,14 @@
"type": "device",
"class": "",
"position": {
- "x": 52.2,
- "y": 14.3,
+ "x": 56.804,
+ "y": 17.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -2885,19 +2892,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -2906,10 +2913,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -2922,14 +2929,14 @@
"type": "device",
"class": "",
"position": {
- "x": 52.2,
- "y": 5.3,
+ "x": 56.804,
+ "y": 8.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -2941,19 +2948,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -2962,10 +2969,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -2978,14 +2985,14 @@
"type": "device",
"class": "",
"position": {
- "x": 61.2,
- "y": 68.3,
+ "x": 65.804,
+ "y": 71.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -2997,19 +3004,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -3018,10 +3025,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -3034,14 +3041,14 @@
"type": "device",
"class": "",
"position": {
- "x": 61.2,
- "y": 59.3,
+ "x": 65.804,
+ "y": 62.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -3053,19 +3060,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -3074,10 +3081,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -3090,14 +3097,14 @@
"type": "device",
"class": "",
"position": {
- "x": 61.2,
- "y": 50.3,
+ "x": 65.804,
+ "y": 53.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -3109,19 +3116,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -3130,10 +3137,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -3146,14 +3153,14 @@
"type": "device",
"class": "",
"position": {
- "x": 61.2,
- "y": 41.3,
+ "x": 65.804,
+ "y": 44.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -3165,19 +3172,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -3186,10 +3193,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -3202,14 +3209,14 @@
"type": "device",
"class": "",
"position": {
- "x": 61.2,
- "y": 32.3,
+ "x": 65.804,
+ "y": 35.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -3221,19 +3228,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -3242,10 +3249,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -3258,14 +3265,14 @@
"type": "device",
"class": "",
"position": {
- "x": 61.2,
- "y": 23.3,
+ "x": 65.804,
+ "y": 26.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -3277,19 +3284,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -3298,10 +3305,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -3314,14 +3321,14 @@
"type": "device",
"class": "",
"position": {
- "x": 61.2,
- "y": 14.3,
+ "x": 65.804,
+ "y": 17.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -3333,19 +3340,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -3354,10 +3361,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -3370,14 +3377,14 @@
"type": "device",
"class": "",
"position": {
- "x": 61.2,
- "y": 5.3,
+ "x": 65.804,
+ "y": 8.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -3389,19 +3396,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -3410,10 +3417,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -3426,14 +3433,14 @@
"type": "device",
"class": "",
"position": {
- "x": 70.2,
- "y": 68.3,
+ "x": 74.804,
+ "y": 71.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -3445,19 +3452,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -3466,10 +3473,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -3482,14 +3489,14 @@
"type": "device",
"class": "",
"position": {
- "x": 70.2,
- "y": 59.3,
+ "x": 74.804,
+ "y": 62.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -3501,19 +3508,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -3522,10 +3529,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -3538,14 +3545,14 @@
"type": "device",
"class": "",
"position": {
- "x": 70.2,
- "y": 50.3,
+ "x": 74.804,
+ "y": 53.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -3557,19 +3564,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -3578,10 +3585,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -3594,14 +3601,14 @@
"type": "device",
"class": "",
"position": {
- "x": 70.2,
- "y": 41.3,
+ "x": 74.804,
+ "y": 44.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -3613,19 +3620,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -3634,10 +3641,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -3650,14 +3657,14 @@
"type": "device",
"class": "",
"position": {
- "x": 70.2,
- "y": 32.3,
+ "x": 74.804,
+ "y": 35.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -3669,19 +3676,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -3690,10 +3697,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -3706,14 +3713,14 @@
"type": "device",
"class": "",
"position": {
- "x": 70.2,
- "y": 23.3,
+ "x": 74.804,
+ "y": 26.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -3725,19 +3732,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -3746,10 +3753,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -3762,14 +3769,14 @@
"type": "device",
"class": "",
"position": {
- "x": 70.2,
- "y": 14.3,
+ "x": 74.804,
+ "y": 17.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -3781,19 +3788,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -3802,10 +3809,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -3818,14 +3825,14 @@
"type": "device",
"class": "",
"position": {
- "x": 70.2,
- "y": 5.3,
+ "x": 74.804,
+ "y": 8.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -3837,19 +3844,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -3858,10 +3865,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -3874,14 +3881,14 @@
"type": "device",
"class": "",
"position": {
- "x": 79.2,
- "y": 68.3,
+ "x": 83.804,
+ "y": 71.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -3893,19 +3900,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -3914,10 +3921,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -3930,14 +3937,14 @@
"type": "device",
"class": "",
"position": {
- "x": 79.2,
- "y": 59.3,
+ "x": 83.804,
+ "y": 62.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -3949,19 +3956,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -3970,10 +3977,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -3986,14 +3993,14 @@
"type": "device",
"class": "",
"position": {
- "x": 79.2,
- "y": 50.3,
+ "x": 83.804,
+ "y": 53.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -4005,19 +4012,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -4026,10 +4033,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -4042,14 +4049,14 @@
"type": "device",
"class": "",
"position": {
- "x": 79.2,
- "y": 41.3,
+ "x": 83.804,
+ "y": 44.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -4061,19 +4068,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -4082,10 +4089,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -4098,14 +4105,14 @@
"type": "device",
"class": "",
"position": {
- "x": 79.2,
- "y": 32.3,
+ "x": 83.804,
+ "y": 35.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -4117,19 +4124,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -4138,10 +4145,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -4154,14 +4161,14 @@
"type": "device",
"class": "",
"position": {
- "x": 79.2,
- "y": 23.3,
+ "x": 83.804,
+ "y": 26.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -4173,19 +4180,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -4194,10 +4201,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -4210,14 +4217,14 @@
"type": "device",
"class": "",
"position": {
- "x": 79.2,
- "y": 14.3,
+ "x": 83.804,
+ "y": 17.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -4229,19 +4236,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -4250,10 +4257,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -4266,14 +4273,14 @@
"type": "device",
"class": "",
"position": {
- "x": 79.2,
- "y": 5.3,
+ "x": 83.804,
+ "y": 8.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -4285,19 +4292,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -4306,10 +4313,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -4322,14 +4329,14 @@
"type": "device",
"class": "",
"position": {
- "x": 88.2,
- "y": 68.3,
+ "x": 92.804,
+ "y": 71.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -4341,19 +4348,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -4362,10 +4369,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -4378,14 +4385,14 @@
"type": "device",
"class": "",
"position": {
- "x": 88.2,
- "y": 59.3,
+ "x": 92.804,
+ "y": 62.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -4397,19 +4404,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -4418,10 +4425,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -4434,14 +4441,14 @@
"type": "device",
"class": "",
"position": {
- "x": 88.2,
- "y": 50.3,
+ "x": 92.804,
+ "y": 53.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -4453,19 +4460,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -4474,10 +4481,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -4490,14 +4497,14 @@
"type": "device",
"class": "",
"position": {
- "x": 88.2,
- "y": 41.3,
+ "x": 92.804,
+ "y": 44.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -4509,19 +4516,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -4530,10 +4537,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -4546,14 +4553,14 @@
"type": "device",
"class": "",
"position": {
- "x": 88.2,
- "y": 32.3,
+ "x": 92.804,
+ "y": 35.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -4565,19 +4572,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -4586,10 +4593,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -4602,14 +4609,14 @@
"type": "device",
"class": "",
"position": {
- "x": 88.2,
- "y": 23.3,
+ "x": 92.804,
+ "y": 26.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -4621,19 +4628,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -4642,10 +4649,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -4658,14 +4665,14 @@
"type": "device",
"class": "",
"position": {
- "x": 88.2,
- "y": 14.3,
+ "x": 92.804,
+ "y": 17.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -4677,19 +4684,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -4698,10 +4705,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -4714,14 +4721,14 @@
"type": "device",
"class": "",
"position": {
- "x": 88.2,
- "y": 5.3,
+ "x": 92.804,
+ "y": 8.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -4733,19 +4740,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -4754,10 +4761,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -4770,14 +4777,14 @@
"type": "device",
"class": "",
"position": {
- "x": 97.2,
- "y": 68.3,
+ "x": 101.804,
+ "y": 71.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -4789,19 +4796,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -4810,10 +4817,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -4826,14 +4833,14 @@
"type": "device",
"class": "",
"position": {
- "x": 97.2,
- "y": 59.3,
+ "x": 101.804,
+ "y": 62.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -4845,19 +4852,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -4866,10 +4873,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -4882,14 +4889,14 @@
"type": "device",
"class": "",
"position": {
- "x": 97.2,
- "y": 50.3,
+ "x": 101.804,
+ "y": 53.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -4901,19 +4908,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -4922,10 +4929,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -4938,14 +4945,14 @@
"type": "device",
"class": "",
"position": {
- "x": 97.2,
- "y": 41.3,
+ "x": 101.804,
+ "y": 44.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -4957,19 +4964,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -4978,10 +4985,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -4994,14 +5001,14 @@
"type": "device",
"class": "",
"position": {
- "x": 97.2,
- "y": 32.3,
+ "x": 101.804,
+ "y": 35.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -5013,19 +5020,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -5034,10 +5041,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -5050,14 +5057,14 @@
"type": "device",
"class": "",
"position": {
- "x": 97.2,
- "y": 23.3,
+ "x": 101.804,
+ "y": 26.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -5069,19 +5076,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -5090,10 +5097,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -5106,14 +5113,14 @@
"type": "device",
"class": "",
"position": {
- "x": 97.2,
- "y": 14.3,
+ "x": 101.804,
+ "y": 17.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -5125,19 +5132,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -5146,10 +5153,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -5162,14 +5169,14 @@
"type": "device",
"class": "",
"position": {
- "x": 97.2,
- "y": 5.3,
+ "x": 101.804,
+ "y": 8.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -5181,19 +5188,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -5202,10 +5209,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -5218,14 +5225,14 @@
"type": "device",
"class": "",
"position": {
- "x": 106.2,
- "y": 68.3,
+ "x": 110.804,
+ "y": 71.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -5237,19 +5244,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -5258,10 +5265,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -5274,14 +5281,14 @@
"type": "device",
"class": "",
"position": {
- "x": 106.2,
- "y": 59.3,
+ "x": 110.804,
+ "y": 62.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -5293,19 +5300,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -5314,10 +5321,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -5330,14 +5337,14 @@
"type": "device",
"class": "",
"position": {
- "x": 106.2,
- "y": 50.3,
+ "x": 110.804,
+ "y": 53.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -5349,19 +5356,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -5370,10 +5377,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -5386,14 +5393,14 @@
"type": "device",
"class": "",
"position": {
- "x": 106.2,
- "y": 41.3,
+ "x": 110.804,
+ "y": 44.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -5405,19 +5412,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -5426,10 +5433,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -5442,14 +5449,14 @@
"type": "device",
"class": "",
"position": {
- "x": 106.2,
- "y": 32.3,
+ "x": 110.804,
+ "y": 35.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -5461,19 +5468,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -5482,10 +5489,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -5498,14 +5505,14 @@
"type": "device",
"class": "",
"position": {
- "x": 106.2,
- "y": 23.3,
+ "x": 110.804,
+ "y": 26.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -5517,19 +5524,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -5538,10 +5545,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -5554,14 +5561,14 @@
"type": "device",
"class": "",
"position": {
- "x": 106.2,
- "y": 14.3,
+ "x": 110.804,
+ "y": 17.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -5573,19 +5580,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -5594,10 +5601,10 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
@@ -5610,14 +5617,14 @@
"type": "device",
"class": "",
"position": {
- "x": 106.2,
- "y": 5.3,
+ "x": 110.804,
+ "y": 8.704,
"z": 9.47
},
"config": {
"type": "TipSpot",
- "size_x": 9.0,
- "size_y": 9.0,
+ "size_x": 5.112,
+ "size_y": 5.112,
"size_z": 0,
"rotation": {
"x": 0,
@@ -5629,19 +5636,19 @@
"model": null,
"prototype_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
},
"data": {
"tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
},
"tip_state": {
"liquids": [],
@@ -5650,13 +5657,16 @@
},
"pending_tip": {
"type": "Tip",
- "total_tip_length": 39.2,
+ "total_tip_length": 88,
"has_filter": true,
- "maximal_volume": 20.0,
- "fitting_depth": 3.29
+ "maximal_volume": 1000.0,
+ "fitting_depth": 7.95
}
}
},
+
+
+
{
"id": "plate_well",
"name": "plate_well",
@@ -5677,7 +5687,7 @@
"plate_well_E2",
"plate_well_F2",
"plate_well_G2",
- "plate_well_H2",
+ "plate_well_H2",
"plate_well_A3",
"plate_well_B3",
"plate_well_C3",
@@ -5756,14 +5766,15 @@
"plate_well_D12",
"plate_well_E12",
"plate_well_F12",
- "plate_well_G12"
+ "plate_well_G12",
+ "plate_well_H12"
],
"parent": "deck",
"type": "plate",
"class": "nest_96_wellplate_2ml_deep",
"position": {
- "x": 265.0,
- "y": 0,
+ "x": 0,
+ "y": 90.5,
"z": 69
},
"config": {
@@ -5880,6 +5891,11 @@
},
"data": {}
},
+
+
+
+
+
{
"id": "plate_well_A1",
"name": "plate_well_A1",
@@ -5889,15 +5905,15 @@
"type": "device",
"class": "",
"position": {
- "x": 10.87,
- "y": 70.77,
- "z": 3.03
+ "x": 10.2,
+ "y": 70.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -5906,16 +5922,16 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
- "liquids": [],
- "pending_liquids": [],
+ "liquids": [["water", 50.0]],
+ "pending_liquids": [["water", 50.0]],
"liquid_history": []
}
},
@@ -5928,15 +5944,15 @@
"type": "device",
"class": "",
"position": {
- "x": 10.87,
- "y": 61.77,
- "z": 3.03
+ "x": 10.2,
+ "y": 61.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -5945,16 +5961,16 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
- "liquids": [],
- "pending_liquids": [],
+ "liquids": [["water", 50.0]],
+ "pending_liquids": [["water", 50.0]],
"liquid_history": []
}
},
@@ -5967,15 +5983,15 @@
"type": "device",
"class": "",
"position": {
- "x": 10.87,
- "y": 52.77,
- "z": 3.03
+ "x": 10.2,
+ "y": 52.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -5984,16 +6000,16 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
- "liquids": [],
- "pending_liquids": [],
+ "liquids": [["water", 50.0]],
+ "pending_liquids": [["water", 50.0]],
"liquid_history": []
}
},
@@ -6006,15 +6022,15 @@
"type": "device",
"class": "",
"position": {
- "x": 10.87,
- "y": 43.77,
- "z": 3.03
+ "x": 10.2,
+ "y": 43.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6023,16 +6039,16 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
- "liquids": [],
- "pending_liquids": [],
+ "liquids": [["water", 50.0]],
+ "pending_liquids": [["water", 50.0]],
"liquid_history": []
}
},
@@ -6045,15 +6061,15 @@
"type": "device",
"class": "",
"position": {
- "x": 10.87,
- "y": 34.77,
- "z": 3.03
+ "x": 10.2,
+ "y": 34.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6062,16 +6078,16 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
- "liquids": [],
- "pending_liquids": [],
+ "liquids": [["water", 50.0]],
+ "pending_liquids": [["water", 50.0]],
"liquid_history": []
}
},
@@ -6084,15 +6100,15 @@
"type": "device",
"class": "",
"position": {
- "x": 10.87,
- "y": 25.77,
- "z": 3.03
+ "x": 10.2,
+ "y": 25.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6101,16 +6117,16 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
- "liquids": [],
- "pending_liquids": [],
+ "liquids": [["water", 50.0]],
+ "pending_liquids": [["water", 50.0]],
"liquid_history": []
}
},
@@ -6123,15 +6139,15 @@
"type": "device",
"class": "",
"position": {
- "x": 10.87,
- "y": 16.77,
- "z": 3.03
+ "x": 10.2,
+ "y": 16.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6140,16 +6156,16 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
- "liquids": [],
- "pending_liquids": [],
+ "liquids": [["water", 50.0]],
+ "pending_liquids": [["water", 50.0]],
"liquid_history": []
}
},
@@ -6162,15 +6178,15 @@
"type": "device",
"class": "",
"position": {
- "x": 10.87,
- "y": 7.77,
- "z": 3.03
+ "x": 10.2,
+ "y": 7.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6179,16 +6195,16 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
- "liquids": [],
- "pending_liquids": [],
+ "liquids": [["water", 50.0]],
+ "pending_liquids": [["water", 50.0]],
"liquid_history": []
}
},
@@ -6201,15 +6217,15 @@
"type": "device",
"class": "",
"position": {
- "x": 19.87,
- "y": 70.77,
- "z": 3.03
+ "x": 19.2,
+ "y": 70.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6218,12 +6234,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -6240,15 +6256,15 @@
"type": "device",
"class": "",
"position": {
- "x": 19.87,
- "y": 61.77,
- "z": 3.03
+ "x": 19.2,
+ "y": 61.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6257,12 +6273,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -6279,15 +6295,15 @@
"type": "device",
"class": "",
"position": {
- "x": 19.87,
- "y": 52.77,
- "z": 3.03
+ "x": 19.2,
+ "y": 52.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6296,12 +6312,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -6318,15 +6334,15 @@
"type": "device",
"class": "",
"position": {
- "x": 19.87,
- "y": 43.77,
- "z": 3.03
+ "x": 19.2,
+ "y": 43.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6335,12 +6351,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -6357,15 +6373,15 @@
"type": "device",
"class": "",
"position": {
- "x": 19.87,
- "y": 34.77,
- "z": 3.03
+ "x": 19.2,
+ "y": 34.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6374,12 +6390,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -6396,15 +6412,15 @@
"type": "device",
"class": "",
"position": {
- "x": 19.87,
- "y": 25.77,
- "z": 3.03
+ "x": 19.2,
+ "y": 25.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6413,12 +6429,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -6435,15 +6451,15 @@
"type": "device",
"class": "",
"position": {
- "x": 19.87,
- "y": 16.77,
- "z": 3.03
+ "x": 19.2,
+ "y": 16.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6452,12 +6468,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -6474,15 +6490,15 @@
"type": "device",
"class": "",
"position": {
- "x": 19.87,
- "y": 7.77,
- "z": 3.03
+ "x": 19.2,
+ "y": 7.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6491,12 +6507,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -6513,15 +6529,15 @@
"type": "device",
"class": "",
"position": {
- "x": 28.87,
- "y": 70.77,
- "z": 3.03
+ "x": 28.2,
+ "y": 70.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6530,12 +6546,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -6552,15 +6568,15 @@
"type": "device",
"class": "",
"position": {
- "x": 28.87,
- "y": 61.77,
- "z": 3.03
+ "x": 28.2,
+ "y": 61.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6569,12 +6585,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -6591,15 +6607,15 @@
"type": "device",
"class": "",
"position": {
- "x": 28.87,
- "y": 52.77,
- "z": 3.03
+ "x": 28.2,
+ "y": 52.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6608,12 +6624,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -6630,15 +6646,15 @@
"type": "device",
"class": "",
"position": {
- "x": 28.87,
- "y": 43.77,
- "z": 3.03
+ "x": 28.2,
+ "y": 43.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6647,12 +6663,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -6669,15 +6685,15 @@
"type": "device",
"class": "",
"position": {
- "x": 28.87,
- "y": 34.77,
- "z": 3.03
+ "x": 28.2,
+ "y": 34.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6686,12 +6702,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -6708,15 +6724,15 @@
"type": "device",
"class": "",
"position": {
- "x": 28.87,
- "y": 25.77,
- "z": 3.03
+ "x": 28.2,
+ "y": 25.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6725,12 +6741,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -6747,15 +6763,15 @@
"type": "device",
"class": "",
"position": {
- "x": 28.87,
- "y": 16.77,
- "z": 3.03
+ "x": 28.2,
+ "y": 16.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6764,12 +6780,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -6786,15 +6802,15 @@
"type": "device",
"class": "",
"position": {
- "x": 28.87,
- "y": 7.77,
- "z": 3.03
+ "x": 28.2,
+ "y": 7.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6803,12 +6819,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -6825,15 +6841,15 @@
"type": "device",
"class": "",
"position": {
- "x": 37.87,
- "y": 70.77,
- "z": 3.03
+ "x": 37.2,
+ "y": 70.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6842,12 +6858,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -6864,15 +6880,15 @@
"type": "device",
"class": "",
"position": {
- "x": 37.87,
- "y": 61.77,
- "z": 3.03
+ "x": 37.2,
+ "y": 61.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6881,12 +6897,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -6903,15 +6919,15 @@
"type": "device",
"class": "",
"position": {
- "x": 37.87,
- "y": 52.77,
- "z": 3.03
+ "x": 37.2,
+ "y": 52.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6920,12 +6936,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -6942,15 +6958,15 @@
"type": "device",
"class": "",
"position": {
- "x": 37.87,
- "y": 43.77,
- "z": 3.03
+ "x": 37.2,
+ "y": 43.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6959,12 +6975,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -6981,15 +6997,15 @@
"type": "device",
"class": "",
"position": {
- "x": 37.87,
- "y": 34.77,
- "z": 3.03
+ "x": 37.2,
+ "y": 34.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -6998,12 +7014,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7020,15 +7036,15 @@
"type": "device",
"class": "",
"position": {
- "x": 37.87,
- "y": 25.77,
- "z": 3.03
+ "x": 37.2,
+ "y": 25.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7037,12 +7053,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7059,15 +7075,15 @@
"type": "device",
"class": "",
"position": {
- "x": 37.87,
- "y": 16.77,
- "z": 3.03
+ "x": 37.2,
+ "y": 16.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7076,12 +7092,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7098,15 +7114,15 @@
"type": "device",
"class": "",
"position": {
- "x": 37.87,
- "y": 7.77,
- "z": 3.03
+ "x": 37.2,
+ "y": 7.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7115,12 +7131,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7137,15 +7153,15 @@
"type": "device",
"class": "",
"position": {
- "x": 46.87,
- "y": 70.77,
- "z": 3.03
+ "x": 46.2,
+ "y": 70.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7154,12 +7170,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7176,15 +7192,15 @@
"type": "device",
"class": "",
"position": {
- "x": 46.87,
- "y": 61.77,
- "z": 3.03
+ "x": 46.2,
+ "y": 61.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7193,12 +7209,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7215,15 +7231,15 @@
"type": "device",
"class": "",
"position": {
- "x": 46.87,
- "y": 52.77,
- "z": 3.03
+ "x": 46.2,
+ "y": 52.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7232,12 +7248,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7254,15 +7270,15 @@
"type": "device",
"class": "",
"position": {
- "x": 46.87,
- "y": 43.77,
- "z": 3.03
+ "x": 46.2,
+ "y": 43.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7271,12 +7287,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7293,15 +7309,15 @@
"type": "device",
"class": "",
"position": {
- "x": 46.87,
- "y": 34.77,
- "z": 3.03
+ "x": 46.2,
+ "y": 34.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7310,12 +7326,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7332,15 +7348,15 @@
"type": "device",
"class": "",
"position": {
- "x": 46.87,
- "y": 25.77,
- "z": 3.03
+ "x": 46.2,
+ "y": 25.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7349,12 +7365,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7371,15 +7387,15 @@
"type": "device",
"class": "",
"position": {
- "x": 46.87,
- "y": 16.77,
- "z": 3.03
+ "x": 46.2,
+ "y": 16.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7388,12 +7404,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7410,15 +7426,15 @@
"type": "device",
"class": "",
"position": {
- "x": 46.87,
- "y": 7.77,
- "z": 3.03
+ "x": 46.2,
+ "y": 7.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7427,12 +7443,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7449,15 +7465,15 @@
"type": "device",
"class": "",
"position": {
- "x": 55.87,
- "y": 70.77,
- "z": 3.03
+ "x": 55.2,
+ "y": 70.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7466,12 +7482,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7488,15 +7504,15 @@
"type": "device",
"class": "",
"position": {
- "x": 55.87,
- "y": 61.77,
- "z": 3.03
+ "x": 55.2,
+ "y": 61.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7505,12 +7521,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7527,15 +7543,15 @@
"type": "device",
"class": "",
"position": {
- "x": 55.87,
- "y": 52.77,
- "z": 3.03
+ "x": 55.2,
+ "y": 52.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7544,12 +7560,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7566,15 +7582,15 @@
"type": "device",
"class": "",
"position": {
- "x": 55.87,
- "y": 43.77,
- "z": 3.03
+ "x": 55.2,
+ "y": 43.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7583,12 +7599,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7605,15 +7621,15 @@
"type": "device",
"class": "",
"position": {
- "x": 55.87,
- "y": 34.77,
- "z": 3.03
+ "x": 55.2,
+ "y": 34.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7622,12 +7638,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7644,15 +7660,15 @@
"type": "device",
"class": "",
"position": {
- "x": 55.87,
- "y": 25.77,
- "z": 3.03
+ "x": 55.2,
+ "y": 25.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7661,12 +7677,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7683,15 +7699,15 @@
"type": "device",
"class": "",
"position": {
- "x": 55.87,
- "y": 16.77,
- "z": 3.03
+ "x": 55.2,
+ "y": 16.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7700,12 +7716,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7722,15 +7738,15 @@
"type": "device",
"class": "",
"position": {
- "x": 55.87,
- "y": 7.77,
- "z": 3.03
+ "x": 55.2,
+ "y": 7.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7739,12 +7755,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7761,15 +7777,15 @@
"type": "device",
"class": "",
"position": {
- "x": 64.87,
- "y": 70.77,
- "z": 3.03
+ "x": 64.2,
+ "y": 70.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7778,12 +7794,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7800,15 +7816,15 @@
"type": "device",
"class": "",
"position": {
- "x": 64.87,
- "y": 61.77,
- "z": 3.03
+ "x": 64.2,
+ "y": 61.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7817,12 +7833,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7839,15 +7855,15 @@
"type": "device",
"class": "",
"position": {
- "x": 64.87,
- "y": 52.77,
- "z": 3.03
+ "x": 64.2,
+ "y": 52.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7856,12 +7872,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7878,15 +7894,15 @@
"type": "device",
"class": "",
"position": {
- "x": 64.87,
- "y": 43.77,
- "z": 3.03
+ "x": 64.2,
+ "y": 43.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7895,12 +7911,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7917,15 +7933,15 @@
"type": "device",
"class": "",
"position": {
- "x": 64.87,
- "y": 34.77,
- "z": 3.03
+ "x": 64.2,
+ "y": 34.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7934,12 +7950,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7956,15 +7972,15 @@
"type": "device",
"class": "",
"position": {
- "x": 64.87,
- "y": 25.77,
- "z": 3.03
+ "x": 64.2,
+ "y": 25.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -7973,12 +7989,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -7995,15 +8011,15 @@
"type": "device",
"class": "",
"position": {
- "x": 64.87,
- "y": 16.77,
- "z": 3.03
+ "x": 64.2,
+ "y": 16.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8012,12 +8028,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8034,15 +8050,15 @@
"type": "device",
"class": "",
"position": {
- "x": 64.87,
- "y": 7.77,
- "z": 3.03
+ "x": 64.2,
+ "y": 7.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8051,12 +8067,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8073,15 +8089,15 @@
"type": "device",
"class": "",
"position": {
- "x": 73.87,
- "y": 70.77,
- "z": 3.03
+ "x": 73.2,
+ "y": 70.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8090,12 +8106,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8112,15 +8128,15 @@
"type": "device",
"class": "",
"position": {
- "x": 73.87,
- "y": 61.77,
- "z": 3.03
+ "x": 73.2,
+ "y": 61.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8129,12 +8145,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8151,15 +8167,15 @@
"type": "device",
"class": "",
"position": {
- "x": 73.87,
- "y": 52.77,
- "z": 3.03
+ "x": 73.2,
+ "y": 52.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8168,12 +8184,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8190,15 +8206,15 @@
"type": "device",
"class": "",
"position": {
- "x": 73.87,
- "y": 43.77,
- "z": 3.03
+ "x": 73.2,
+ "y": 43.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8207,12 +8223,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8229,15 +8245,15 @@
"type": "device",
"class": "",
"position": {
- "x": 73.87,
- "y": 34.77,
- "z": 3.03
+ "x": 73.2,
+ "y": 34.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8246,12 +8262,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8268,15 +8284,15 @@
"type": "device",
"class": "",
"position": {
- "x": 73.87,
- "y": 25.77,
- "z": 3.03
+ "x": 73.2,
+ "y": 25.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8285,12 +8301,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8307,15 +8323,15 @@
"type": "device",
"class": "",
"position": {
- "x": 73.87,
- "y": 16.77,
- "z": 3.03
+ "x": 73.2,
+ "y": 16.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8324,12 +8340,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8346,15 +8362,15 @@
"type": "device",
"class": "",
"position": {
- "x": 73.87,
- "y": 7.77,
- "z": 3.03
+ "x": 73.2,
+ "y": 7.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8363,12 +8379,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8385,15 +8401,15 @@
"type": "device",
"class": "",
"position": {
- "x": 82.87,
- "y": 70.77,
- "z": 3.03
+ "x": 82.2,
+ "y": 70.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8402,12 +8418,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8424,15 +8440,15 @@
"type": "device",
"class": "",
"position": {
- "x": 82.87,
- "y": 61.77,
- "z": 3.03
+ "x": 82.2,
+ "y": 61.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8441,12 +8457,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8463,15 +8479,15 @@
"type": "device",
"class": "",
"position": {
- "x": 82.87,
- "y": 52.77,
- "z": 3.03
+ "x": 82.2,
+ "y": 52.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8480,12 +8496,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8502,15 +8518,15 @@
"type": "device",
"class": "",
"position": {
- "x": 82.87,
- "y": 43.77,
- "z": 3.03
+ "x": 82.2,
+ "y": 43.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8519,12 +8535,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8541,15 +8557,15 @@
"type": "device",
"class": "",
"position": {
- "x": 82.87,
- "y": 34.77,
- "z": 3.03
+ "x": 82.2,
+ "y": 34.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8558,12 +8574,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8580,15 +8596,15 @@
"type": "device",
"class": "",
"position": {
- "x": 82.87,
- "y": 25.77,
- "z": 3.03
+ "x": 82.2,
+ "y": 25.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8597,12 +8613,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8619,15 +8635,15 @@
"type": "device",
"class": "",
"position": {
- "x": 82.87,
- "y": 16.77,
- "z": 3.03
+ "x": 82.2,
+ "y": 16.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8636,12 +8652,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8658,15 +8674,15 @@
"type": "device",
"class": "",
"position": {
- "x": 82.87,
- "y": 7.77,
- "z": 3.03
+ "x": 82.2,
+ "y": 7.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8675,12 +8691,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8697,15 +8713,15 @@
"type": "device",
"class": "",
"position": {
- "x": 91.87,
- "y": 70.77,
- "z": 3.03
+ "x": 91.2,
+ "y": 70.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8714,12 +8730,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8736,15 +8752,15 @@
"type": "device",
"class": "",
"position": {
- "x": 91.87,
- "y": 61.77,
- "z": 3.03
+ "x": 91.2,
+ "y": 61.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8753,12 +8769,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8775,15 +8791,15 @@
"type": "device",
"class": "",
"position": {
- "x": 91.87,
- "y": 52.77,
- "z": 3.03
+ "x": 91.2,
+ "y": 52.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8792,12 +8808,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8814,15 +8830,15 @@
"type": "device",
"class": "",
"position": {
- "x": 91.87,
- "y": 43.77,
- "z": 3.03
+ "x": 91.2,
+ "y": 43.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8831,12 +8847,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8853,15 +8869,15 @@
"type": "device",
"class": "",
"position": {
- "x": 91.87,
- "y": 34.77,
- "z": 3.03
+ "x": 91.2,
+ "y": 34.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8870,12 +8886,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8892,15 +8908,15 @@
"type": "device",
"class": "",
"position": {
- "x": 91.87,
- "y": 25.77,
- "z": 3.03
+ "x": 91.2,
+ "y": 25.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8909,12 +8925,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8931,15 +8947,15 @@
"type": "device",
"class": "",
"position": {
- "x": 91.87,
- "y": 16.77,
- "z": 3.03
+ "x": 91.2,
+ "y": 16.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8948,12 +8964,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -8970,15 +8986,15 @@
"type": "device",
"class": "",
"position": {
- "x": 91.87,
- "y": 7.77,
- "z": 3.03
+ "x": 91.2,
+ "y": 7.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -8987,12 +9003,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -9009,15 +9025,15 @@
"type": "device",
"class": "",
"position": {
- "x": 100.87,
- "y": 70.77,
- "z": 3.03
+ "x": 100.2,
+ "y": 70.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -9026,12 +9042,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -9048,15 +9064,15 @@
"type": "device",
"class": "",
"position": {
- "x": 100.87,
- "y": 61.77,
- "z": 3.03
+ "x": 100.2,
+ "y": 61.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -9065,12 +9081,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -9087,15 +9103,15 @@
"type": "device",
"class": "",
"position": {
- "x": 100.87,
- "y": 52.77,
- "z": 3.03
+ "x": 100.2,
+ "y": 52.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -9104,12 +9120,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -9126,15 +9142,15 @@
"type": "device",
"class": "",
"position": {
- "x": 100.87,
- "y": 43.77,
- "z": 3.03
+ "x": 100.2,
+ "y": 43.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -9143,12 +9159,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -9165,15 +9181,15 @@
"type": "device",
"class": "",
"position": {
- "x": 100.87,
- "y": 34.77,
- "z": 3.03
+ "x": 100.2,
+ "y": 34.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -9182,12 +9198,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -9204,15 +9220,15 @@
"type": "device",
"class": "",
"position": {
- "x": 100.87,
- "y": 25.77,
- "z": 3.03
+ "x": 100.2,
+ "y": 25.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -9221,12 +9237,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -9243,15 +9259,15 @@
"type": "device",
"class": "",
"position": {
- "x": 100.87,
- "y": 16.77,
- "z": 3.03
+ "x": 100.2,
+ "y": 16.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -9260,12 +9276,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -9282,15 +9298,15 @@
"type": "device",
"class": "",
"position": {
- "x": 100.87,
- "y": 7.77,
- "z": 3.03
+ "x": 100.2,
+ "y": 7.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -9299,12 +9315,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -9321,15 +9337,15 @@
"type": "device",
"class": "",
"position": {
- "x": 109.87,
- "y": 70.77,
- "z": 3.03
+ "x": 109.2,
+ "y": 70.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -9338,12 +9354,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -9360,15 +9376,15 @@
"type": "device",
"class": "",
"position": {
- "x": 109.87,
- "y": 61.77,
- "z": 3.03
+ "x": 109.2,
+ "y": 61.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -9377,12 +9393,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -9399,15 +9415,15 @@
"type": "device",
"class": "",
"position": {
- "x": 109.87,
- "y": 52.77,
- "z": 3.03
+ "x": 109.2,
+ "y": 52.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -9416,12 +9432,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -9438,15 +9454,15 @@
"type": "device",
"class": "",
"position": {
- "x": 109.87,
- "y": 43.77,
- "z": 3.03
+ "x": 109.2,
+ "y": 43.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -9455,12 +9471,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -9477,15 +9493,15 @@
"type": "device",
"class": "",
"position": {
- "x": 109.87,
- "y": 34.77,
- "z": 3.03
+ "x": 109.2,
+ "y": 34.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -9494,12 +9510,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -9516,15 +9532,15 @@
"type": "device",
"class": "",
"position": {
- "x": 109.87,
- "y": 25.77,
- "z": 3.03
+ "x": 109.2,
+ "y": 25.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -9533,12 +9549,12 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
@@ -9555,15 +9571,15 @@
"type": "device",
"class": "",
"position": {
- "x": 109.87,
- "y": 16.77,
- "z": 3.03
+ "x": 109.2,
+ "y": 16.05,
+ "z": 3
},
"config": {
"type": "Well",
- "size_x": 6.86,
- "size_y": 6.86,
- "size_z": 10.67,
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
"rotation": {
"x": 0,
"y": 0,
@@ -9572,18 +9588,126 @@
},
"category": "well",
"model": null,
- "max_volume": 360,
- "material_z_thickness": 0.5,
+ "max_volume": 2000,
+ "material_z_thickness": null,
"compute_volume_from_height": null,
"compute_height_from_volume": null,
- "bottom_type": "flat",
- "cross_section_type": "circle"
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
},
"data": {
"liquids": [],
"pending_liquids": [],
"liquid_history": []
}
+ },
+ {
+ "id": "plate_well_H12",
+ "name": "plate_well_H12",
+ "sample_id": null,
+ "children": [],
+ "parent": "plate_well",
+ "type": "device",
+ "class": "",
+ "position": {
+ "x": 109.2,
+ "y": 7.05,
+ "z": 3
+ },
+ "config": {
+ "type": "Well",
+ "size_x": 8.2,
+ "size_y": 8.2,
+ "size_z": 38,
+ "rotation": {
+ "x": 0,
+ "y": 0,
+ "z": 0,
+ "type": "Rotation"
+ },
+ "category": "well",
+ "model": null,
+ "max_volume": 2000,
+ "material_z_thickness": null,
+ "compute_volume_from_height": null,
+ "compute_height_from_volume": null,
+ "bottom_type": "unknown",
+ "cross_section_type": "rectangle"
+ },
+ "data": {
+ "liquids": [],
+ "pending_liquids": [],
+ "liquid_history": []
+ }
+ },
+
+
+
+
+ {
+ "id": "benyao",
+ "name": "benyao",
+ "children": [],
+ "parent": null,
+ "type": "device",
+ "class": "moveit.benyao_arm",
+ "position": {
+ "x": -500,
+ "y": 1000,
+ "z": -100
+ },
+ "config": {
+ "moveit_type": "benyao_arm",
+ "joint_poses": {
+ "arm": {
+ "hotel_1": [
+ 1.05,
+ 0.568,
+ -1.0821,
+ 0.0,
+ 1.0821
+ ],
+ "home": [
+ 0.865,
+ 0.09,
+ 0.8727,
+ 0.0,
+ -0.8727
+ ]
+ }
+ },
+ "rotation": {
+ "x": 0,
+ "y": 0,
+ "z": -1.5708,
+ "type": "Rotation"
+ },
+ "device_config": {}
+ },
+ "data": {}
+ },
+ {
+ "id": "hotel",
+ "name": "hotel",
+ "children": [],
+ "parent": null,
+ "type": "device",
+ "class": "hotel.thermo_orbitor_rs2_hotel",
+ "position": {
+ "x": 0,
+ "y": -700,
+ "z": -10
+ },
+ "config": {
+ "rotation": {
+ "x": 0,
+ "y": 0,
+ "z": 0,
+ "type": "Rotation"
+ },
+ "device_config": {}
+ },
+ "data": {}
}
],
"links": []
diff --git a/test/experiments/test_moveit.json b/test/experiments/test_moveit.json
new file mode 100644
index 0000000..2859dc3
--- /dev/null
+++ b/test/experiments/test_moveit.json
@@ -0,0 +1,35 @@
+{
+ "nodes": [
+
+ {
+ "id": "benyao",
+ "name": "benyao",
+ "children": [
+ ],
+ "parent": null,
+ "type": "device",
+ "class": "moveit.benyao_arm",
+ "position": {
+ "x": 0,
+ "y": 0,
+ "z": 0
+ },
+ "config": {
+ "moveit_type": "benyao_arm",
+ "joint_poses": {
+ "arm": {
+ "home": [0.0, 0.2, 0.0, 0.0, 0.0],
+ "pick": [1.2, 0.0, 0.0, 0.0, 0.0]
+ }
+ },
+ "device_config": {
+ }
+ },
+ "data": {
+ }
+ }
+ ],
+ "links": [
+
+ ]
+}
\ No newline at end of file
diff --git a/unilabos/app/mq.py b/unilabos/app/mq.py
index dbaa57c..fbd57b9 100644
--- a/unilabos/app/mq.py
+++ b/unilabos/app/mq.py
@@ -162,7 +162,7 @@ class MQTTClient:
status = {"data": device_status.get(device_id, {}), "device_id": device_id}
address = f"labs/{MQConfig.lab_id}/devices/"
self.client.publish(address, json.dumps(status), qos=2)
- logger.critical(f"Device status published: address: {address}, {status}")
+ logger.debug(f"Device status published: address: {address}, {status}")
def publish_job_status(self, feedback_data: dict, job_id: str, status: str, return_info: Optional[str] = None):
if self.mqtt_disable:
diff --git a/unilabos/app/web/client.py b/unilabos/app/web/client.py
index 648859f..6932948 100644
--- a/unilabos/app/web/client.py
+++ b/unilabos/app/web/client.py
@@ -60,7 +60,7 @@ class HTTPClient:
Dict: 返回的资源数据
"""
response = requests.get(
- f"{self.remote_addr}/lab/resource/",
+ f"{self.remote_addr}/lab/resource/?edge_format=1",
params={"id": id, "with_children": with_children},
headers={"Authorization": f"lab {self.auth}"},
timeout=5,
@@ -96,7 +96,7 @@ class HTTPClient:
Response: API响应对象
"""
response = requests.patch(
- f"{self.remote_addr}/lab/resource/batch_update/",
+ f"{self.remote_addr}/lab/resource/batch_update/?edge_format=1",
json=resources,
headers={"Authorization": f"lab {self.auth}"},
timeout=5,
diff --git a/unilabos/device_mesh/devices/benyao_arm/config/initial_positions.yaml b/unilabos/device_mesh/devices/benyao_arm/config/initial_positions.yaml
new file mode 100644
index 0000000..94fb9f5
--- /dev/null
+++ b/unilabos/device_mesh/devices/benyao_arm/config/initial_positions.yaml
@@ -0,0 +1,9 @@
+# Default initial positions for full_dev's ros2_control fake system
+
+initial_positions:
+ arm_base_joint: 0
+ arm_link_1_joint: 0
+ arm_link_2_joint: 0
+ arm_link_3_joint: 0
+ gripper_base_joint: 0
+ gripper_right_joint: 0.03
\ No newline at end of file
diff --git a/unilabos/device_mesh/devices/benyao_arm/config/joint_limits.yaml b/unilabos/device_mesh/devices/benyao_arm/config/joint_limits.yaml
new file mode 100644
index 0000000..d4dffc3
--- /dev/null
+++ b/unilabos/device_mesh/devices/benyao_arm/config/joint_limits.yaml
@@ -0,0 +1,40 @@
+# joint_limits.yaml allows the dynamics properties specified in the URDF to be overwritten or augmented as needed
+
+# For beginners, we downscale velocity and acceleration limits.
+# You can always specify higher scaling factors (<= 1.0) in your motion requests. # Increase the values below to 1.0 to always move at maximum speed.
+default_velocity_scaling_factor: 0.1
+default_acceleration_scaling_factor: 0.1
+
+# Specific joint properties can be changed with the keys [max_position, min_position, max_velocity, max_acceleration]
+# Joint limits can be turned off with [has_velocity_limits, has_acceleration_limits]
+joint_limits:
+ arm_base_joint:
+ has_velocity_limits: true
+ max_velocity: 0
+ has_acceleration_limits: false
+ max_acceleration: 0
+ arm_link_1_joint:
+ has_velocity_limits: true
+ max_velocity: 0
+ has_acceleration_limits: false
+ max_acceleration: 0
+ arm_link_2_joint:
+ has_velocity_limits: true
+ max_velocity: 0
+ has_acceleration_limits: false
+ max_acceleration: 0
+ arm_link_3_joint:
+ has_velocity_limits: true
+ max_velocity: 0
+ has_acceleration_limits: false
+ max_acceleration: 0
+ gripper_base_joint:
+ has_velocity_limits: true
+ max_velocity: 0
+ has_acceleration_limits: false
+ max_acceleration: 0
+ gripper_right_joint:
+ has_velocity_limits: true
+ max_velocity: 0
+ has_acceleration_limits: false
+ max_acceleration: 0
\ No newline at end of file
diff --git a/unilabos/device_mesh/devices/benyao_arm/config/kinematics.yaml b/unilabos/device_mesh/devices/benyao_arm/config/kinematics.yaml
new file mode 100644
index 0000000..c9a5d60
--- /dev/null
+++ b/unilabos/device_mesh/devices/benyao_arm/config/kinematics.yaml
@@ -0,0 +1,4 @@
+arm:
+ kinematics_solver: lma_kinematics_plugin/LMAKinematicsPlugin
+ kinematics_solver_search_resolution: 0.0050000000000000001
+ kinematics_solver_timeout: 0.0050000000000000001
diff --git a/unilabos/device_mesh/devices/benyao_arm/config/macro.ros2_control.xacro b/unilabos/device_mesh/devices/benyao_arm/config/macro.ros2_control.xacro
new file mode 100644
index 0000000..70f8634
--- /dev/null
+++ b/unilabos/device_mesh/devices/benyao_arm/config/macro.ros2_control.xacro
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+ mock_components/GenericSystem
+
+
+
+
+ ${initial_positions['arm_base_joint']}
+
+
+
+
+
+
+ ${initial_positions['arm_link_1_joint']}
+
+
+
+
+
+
+ ${initial_positions['arm_link_2_joint']}
+
+
+
+
+
+
+ ${initial_positions['arm_link_3_joint']}
+
+
+
+
+
+
+ ${initial_positions['gripper_base_joint']}
+
+
+
+
+
+
+ ${initial_positions['gripper_right_joint']}
+
+
+
+
+
+
+
diff --git a/unilabos/device_mesh/devices/benyao_arm/config/macro.srdf.xacro b/unilabos/device_mesh/devices/benyao_arm/config/macro.srdf.xacro
new file mode 100644
index 0000000..aeb5677
--- /dev/null
+++ b/unilabos/device_mesh/devices/benyao_arm/config/macro.srdf.xacro
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/unilabos/device_mesh/devices/benyao_arm/config/move_group.json b/unilabos/device_mesh/devices/benyao_arm/config/move_group.json
new file mode 100644
index 0000000..5be9ad3
--- /dev/null
+++ b/unilabos/device_mesh/devices/benyao_arm/config/move_group.json
@@ -0,0 +1,14 @@
+{
+ "arm":
+ {
+ "joint_names": [
+ "arm_base_joint",
+ "arm_link_1_joint",
+ "arm_link_2_joint",
+ "arm_link_3_joint",
+ "gripper_base_joint"
+ ],
+ "base_link_name": "device_link",
+ "end_effector_name": "gripper_base"
+ }
+}
\ No newline at end of file
diff --git a/unilabos/device_mesh/devices/benyao_arm/config/moveit_controllers.yaml b/unilabos/device_mesh/devices/benyao_arm/config/moveit_controllers.yaml
new file mode 100644
index 0000000..70a1b55
--- /dev/null
+++ b/unilabos/device_mesh/devices/benyao_arm/config/moveit_controllers.yaml
@@ -0,0 +1,29 @@
+# MoveIt uses this configuration for controller management
+
+moveit_controller_manager: moveit_simple_controller_manager/MoveItSimpleControllerManager
+
+moveit_simple_controller_manager:
+ controller_names:
+ - arm_controller
+ - gripper_controller
+
+ arm_controller:
+ type: FollowJointTrajectory
+ action_ns: follow_joint_trajectory
+ default: true
+ joints:
+ - arm_base_joint
+ - arm_link_1_joint
+ - arm_link_2_joint
+ - arm_link_3_joint
+ - gripper_base_joint
+ action_ns: follow_joint_trajectory
+ default: true
+ gripper_controller:
+ type: FollowJointTrajectory
+ action_ns: follow_joint_trajectory
+ default: true
+ joints:
+ - gripper_right_joint
+ action_ns: follow_joint_trajectory
+ default: true
\ No newline at end of file
diff --git a/unilabos/device_mesh/devices/benyao_arm/config/moveit_planners.yaml b/unilabos/device_mesh/devices/benyao_arm/config/moveit_planners.yaml
new file mode 100644
index 0000000..8560e1c
--- /dev/null
+++ b/unilabos/device_mesh/devices/benyao_arm/config/moveit_planners.yaml
@@ -0,0 +1,2 @@
+planner_configs:
+ - ompl_interface/OMPLPlanner
\ No newline at end of file
diff --git a/unilabos/device_mesh/devices/benyao_arm/config/pilz_cartesian_limits.yaml b/unilabos/device_mesh/devices/benyao_arm/config/pilz_cartesian_limits.yaml
new file mode 100644
index 0000000..b2997ca
--- /dev/null
+++ b/unilabos/device_mesh/devices/benyao_arm/config/pilz_cartesian_limits.yaml
@@ -0,0 +1,6 @@
+# Limits for the Pilz planner
+cartesian_limits:
+ max_trans_vel: 1.0
+ max_trans_acc: 2.25
+ max_trans_dec: -5.0
+ max_rot_vel: 1.57
diff --git a/unilabos/device_mesh/devices/benyao_arm/config/ros2_controllers.yaml b/unilabos/device_mesh/devices/benyao_arm/config/ros2_controllers.yaml
new file mode 100644
index 0000000..9c68cbf
--- /dev/null
+++ b/unilabos/device_mesh/devices/benyao_arm/config/ros2_controllers.yaml
@@ -0,0 +1,39 @@
+# This config file is used by ros2_control
+controller_manager:
+ ros__parameters:
+ update_rate: 100 # Hz
+
+ arm_controller:
+ type: joint_trajectory_controller/JointTrajectoryController
+
+
+ gripper_controller:
+ type: joint_trajectory_controller/JointTrajectoryController
+
+
+ joint_state_broadcaster:
+ type: joint_state_broadcaster/JointStateBroadcaster
+
+arm_controller:
+ ros__parameters:
+ joints:
+ - arm_base_joint
+ - arm_link_1_joint
+ - arm_link_2_joint
+ - arm_link_3_joint
+ - gripper_base_joint
+ command_interfaces:
+ - position
+ state_interfaces:
+ - position
+ - velocity
+
+gripper_controller:
+ ros__parameters:
+ joints:
+ - gripper_right_joint
+ command_interfaces:
+ - position
+ state_interfaces:
+ - position
+ - velocity
\ No newline at end of file
diff --git a/unilabos/device_mesh/devices/benyao_arm/joint_limit.yaml b/unilabos/device_mesh/devices/benyao_arm/joint_limit.yaml
new file mode 100644
index 0000000..b141262
--- /dev/null
+++ b/unilabos/device_mesh/devices/benyao_arm/joint_limit.yaml
@@ -0,0 +1,44 @@
+joint_limits:
+
+ arm_base_joint:
+ effort: 50
+ velocity: 1.0
+ lower: 0
+ upper: 1.5
+
+ arm_link_1_joint:
+ effort: 50
+ velocity: 1.0
+ lower: 0
+ upper: 0.6
+
+ arm_link_2_joint:
+ effort: 50
+ velocity: 1.0
+ lower: !degrees -95
+ upper: !degrees 95
+
+ arm_link_3_joint:
+ effort: 50
+ velocity: 1.0
+ lower: !degrees -195
+ upper: !degrees 195
+
+ gripper_base_joint:
+ effort: 50
+ velocity: 1.0
+ lower: !degrees -95
+ upper: !degrees 95
+
+
+ gripper_right_joint:
+ effort: 50
+ velocity: 1.0
+ lower: 0
+ upper: 0.03
+
+ gripper_left_joint:
+ effort: 50
+ velocity: 1.0
+ lower: 0
+ upper: 0.03
diff --git a/unilabos/device_mesh/devices/benyao_arm/macro_device.xacro b/unilabos/device_mesh/devices/benyao_arm/macro_device.xacro
new file mode 100644
index 0000000..137c916
--- /dev/null
+++ b/unilabos/device_mesh/devices/benyao_arm/macro_device.xacro
@@ -0,0 +1,293 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/unilabos/device_mesh/devices/benyao_arm/meshes/arm_base.STL b/unilabos/device_mesh/devices/benyao_arm/meshes/arm_base.STL
new file mode 100644
index 0000000..804e1c6
Binary files /dev/null and b/unilabos/device_mesh/devices/benyao_arm/meshes/arm_base.STL differ
diff --git a/unilabos/device_mesh/devices/benyao_arm/meshes/arm_link_1.STL b/unilabos/device_mesh/devices/benyao_arm/meshes/arm_link_1.STL
new file mode 100644
index 0000000..dd1d7c1
Binary files /dev/null and b/unilabos/device_mesh/devices/benyao_arm/meshes/arm_link_1.STL differ
diff --git a/unilabos/device_mesh/devices/benyao_arm/meshes/arm_link_2.STL b/unilabos/device_mesh/devices/benyao_arm/meshes/arm_link_2.STL
new file mode 100644
index 0000000..6042fa0
Binary files /dev/null and b/unilabos/device_mesh/devices/benyao_arm/meshes/arm_link_2.STL differ
diff --git a/unilabos/device_mesh/devices/benyao_arm/meshes/arm_link_3.STL b/unilabos/device_mesh/devices/benyao_arm/meshes/arm_link_3.STL
new file mode 100644
index 0000000..e8510fb
Binary files /dev/null and b/unilabos/device_mesh/devices/benyao_arm/meshes/arm_link_3.STL differ
diff --git a/unilabos/device_mesh/devices/benyao_arm/meshes/arm_slideway.STL b/unilabos/device_mesh/devices/benyao_arm/meshes/arm_slideway.STL
new file mode 100644
index 0000000..65737ab
Binary files /dev/null and b/unilabos/device_mesh/devices/benyao_arm/meshes/arm_slideway.STL differ
diff --git a/unilabos/device_mesh/devices/benyao_arm/meshes/gripper_base.STL b/unilabos/device_mesh/devices/benyao_arm/meshes/gripper_base.STL
new file mode 100644
index 0000000..5de88d0
Binary files /dev/null and b/unilabos/device_mesh/devices/benyao_arm/meshes/gripper_base.STL differ
diff --git a/unilabos/device_mesh/devices/benyao_arm/meshes/gripper_left.STL b/unilabos/device_mesh/devices/benyao_arm/meshes/gripper_left.STL
new file mode 100644
index 0000000..0a5fd52
Binary files /dev/null and b/unilabos/device_mesh/devices/benyao_arm/meshes/gripper_left.STL differ
diff --git a/unilabos/device_mesh/devices/benyao_arm/meshes/gripper_right.STL b/unilabos/device_mesh/devices/benyao_arm/meshes/gripper_right.STL
new file mode 100644
index 0000000..0c5ac69
Binary files /dev/null and b/unilabos/device_mesh/devices/benyao_arm/meshes/gripper_right.STL differ
diff --git a/unilabos/device_mesh/devices/opentrons_liquid_handler/macro_device.xacro b/unilabos/device_mesh/devices/opentrons_liquid_handler/macro_device.xacro
index 4e66055..f76f654 100644
--- a/unilabos/device_mesh/devices/opentrons_liquid_handler/macro_device.xacro
+++ b/unilabos/device_mesh/devices/opentrons_liquid_handler/macro_device.xacro
@@ -3,11 +3,10 @@
-
+ params="parent_link:='' station_name:='' device_name:='' x:=0 y:=0 z:=0 rx:=0 ry:=0 r:=0 mesh_path:=''">
-
+
diff --git a/unilabos/device_mesh/devices/slide_w140/macro_device.xacro b/unilabos/device_mesh/devices/slide_w140/macro_device.xacro
index 7e43242..d6d93f9 100644
--- a/unilabos/device_mesh/devices/slide_w140/macro_device.xacro
+++ b/unilabos/device_mesh/devices/slide_w140/macro_device.xacro
@@ -8,11 +8,11 @@
For more information, please see http://wiki.ros.org/sw_urdf_exporter -->
-
+
-
+
diff --git a/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/hotel.png b/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/hotel.png
new file mode 100644
index 0000000..daecc63
Binary files /dev/null and b/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/hotel.png differ
diff --git a/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/macro_device.xacro b/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/macro_device.xacro
new file mode 100644
index 0000000..52c9536
--- /dev/null
+++ b/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/macro_device.xacro
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/meshes/hotel.glb b/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/meshes/hotel.glb
new file mode 100644
index 0000000..724b85f
Binary files /dev/null and b/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/meshes/hotel.glb differ
diff --git a/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/meshes/hotel.stl b/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/meshes/hotel.stl
new file mode 100644
index 0000000..59cb908
Binary files /dev/null and b/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/meshes/hotel.stl differ
diff --git a/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/meta.json b/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/meta.json
new file mode 100644
index 0000000..b8f35cb
--- /dev/null
+++ b/unilabos/device_mesh/devices/thermo_orbitor_rs2_hotel/meta.json
@@ -0,0 +1,10 @@
+{
+ "fileName": "thermo_orbitor_rs2_hotel",
+ "related": [
+ "thermo_skyline_stacker",
+ "thermo_cytomat2c_stacker_15",
+ "thermo_fisher_cytomat_stacker_16",
+ "thermo_cytomat2c_stacker_21",
+ "thermo_orbitor_rs2_hotel"
+ ]
+}
diff --git a/unilabos/device_mesh/devices/toyo_xyz/config/full_dev.urdf.xacro b/unilabos/device_mesh/devices/toyo_xyz/config/full_dev.urdf.xacro
new file mode 100644
index 0000000..29bd48d
--- /dev/null
+++ b/unilabos/device_mesh/devices/toyo_xyz/config/full_dev.urdf.xacro
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/unilabos/device_mesh/devices/toyo_xyz/config/initial_positions.yaml b/unilabos/device_mesh/devices/toyo_xyz/config/initial_positions.yaml
new file mode 100644
index 0000000..d44ccee
--- /dev/null
+++ b/unilabos/device_mesh/devices/toyo_xyz/config/initial_positions.yaml
@@ -0,0 +1,6 @@
+# Default initial positions for full_dev's ros2_control fake system
+
+initial_positions:
+ slider1_joint: 0
+ slider2_joint: 0
+ slider3_joint: 0
\ No newline at end of file
diff --git a/unilabos/device_mesh/devices/toyo_xyz/config/joint_limits.yaml b/unilabos/device_mesh/devices/toyo_xyz/config/joint_limits.yaml
new file mode 100644
index 0000000..251b26c
--- /dev/null
+++ b/unilabos/device_mesh/devices/toyo_xyz/config/joint_limits.yaml
@@ -0,0 +1,25 @@
+# joint_limits.yaml allows the dynamics properties specified in the URDF to be overwritten or augmented as needed
+
+# For beginners, we downscale velocity and acceleration limits.
+# You can always specify higher scaling factors (<= 1.0) in your motion requests. # Increase the values below to 1.0 to always move at maximum speed.
+default_velocity_scaling_factor: 0.1
+default_acceleration_scaling_factor: 0.1
+
+# Specific joint properties can be changed with the keys [max_position, min_position, max_velocity, max_acceleration]
+# Joint limits can be turned off with [has_velocity_limits, has_acceleration_limits]
+joint_limits:
+ slider1_joint:
+ has_velocity_limits: false
+ max_velocity: 0
+ has_acceleration_limits: false
+ max_acceleration: 0
+ slider2_joint:
+ has_velocity_limits: false
+ max_velocity: 0
+ has_acceleration_limits: false
+ max_acceleration: 0
+ slider3_joint:
+ has_velocity_limits: false
+ max_velocity: 0
+ has_acceleration_limits: false
+ max_acceleration: 0
\ No newline at end of file
diff --git a/unilabos/device_mesh/devices/toyo_xyz/config/kinematics.yaml b/unilabos/device_mesh/devices/toyo_xyz/config/kinematics.yaml
new file mode 100644
index 0000000..d11fa7b
--- /dev/null
+++ b/unilabos/device_mesh/devices/toyo_xyz/config/kinematics.yaml
@@ -0,0 +1,4 @@
+toyo_xyz:
+ kinematics_solver: lma_kinematics_plugin/LMAKinematicsPlugin
+ kinematics_solver_search_resolution: 0.0050000000000000001
+ kinematics_solver_timeout: 0.0050000000000000001
\ No newline at end of file
diff --git a/unilabos/device_mesh/devices/toyo_xyz/config/macro.ros2_control.xacro b/unilabos/device_mesh/devices/toyo_xyz/config/macro.ros2_control.xacro
new file mode 100644
index 0000000..5bc3404
--- /dev/null
+++ b/unilabos/device_mesh/devices/toyo_xyz/config/macro.ros2_control.xacro
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+ mock_components/GenericSystem
+
+
+
+
+ ${initial_positions['slider1_joint']}
+
+
+
+
+
+
+ ${initial_positions['slider2_joint']}
+
+
+
+
+
+
+ ${initial_positions['slider3_joint']}
+
+
+
+
+
+
+
diff --git a/unilabos/device_mesh/devices/toyo_xyz/config/macro.srdf.xacro b/unilabos/device_mesh/devices/toyo_xyz/config/macro.srdf.xacro
new file mode 100644
index 0000000..753382f
--- /dev/null
+++ b/unilabos/device_mesh/devices/toyo_xyz/config/macro.srdf.xacro
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/unilabos/device_mesh/devices/toyo_xyz/config/move_group.json b/unilabos/device_mesh/devices/toyo_xyz/config/move_group.json
new file mode 100644
index 0000000..d900674
--- /dev/null
+++ b/unilabos/device_mesh/devices/toyo_xyz/config/move_group.json
@@ -0,0 +1,12 @@
+{
+ "toyo_xyz":
+ {
+ "joint_names": [
+ "slider1_joint",
+ "slider2_joint",
+ "slider3_joint"
+ ],
+ "base_link_name": "device_link",
+ "end_effector_name": "slider3_link"
+ }
+}
\ No newline at end of file
diff --git a/unilabos/device_mesh/devices/toyo_xyz/config/moveit_controllers.yaml b/unilabos/device_mesh/devices/toyo_xyz/config/moveit_controllers.yaml
new file mode 100644
index 0000000..0fcac51
--- /dev/null
+++ b/unilabos/device_mesh/devices/toyo_xyz/config/moveit_controllers.yaml
@@ -0,0 +1,16 @@
+# MoveIt uses this configuration for controller management
+
+moveit_controller_manager: moveit_simple_controller_manager/MoveItSimpleControllerManager
+
+moveit_simple_controller_manager:
+ controller_names:
+ - toyo_xyz_controller
+
+ toyo_xyz_controller:
+ type: FollowJointTrajectory
+ action_ns: follow_joint_trajectory
+ default: true
+ joints:
+ - slider1_joint
+ - slider2_joint
+ - slider3_joint
\ No newline at end of file
diff --git a/unilabos/device_mesh/devices/toyo_xyz/config/pilz_cartesian_limits.yaml b/unilabos/device_mesh/devices/toyo_xyz/config/pilz_cartesian_limits.yaml
new file mode 100644
index 0000000..b2997ca
--- /dev/null
+++ b/unilabos/device_mesh/devices/toyo_xyz/config/pilz_cartesian_limits.yaml
@@ -0,0 +1,6 @@
+# Limits for the Pilz planner
+cartesian_limits:
+ max_trans_vel: 1.0
+ max_trans_acc: 2.25
+ max_trans_dec: -5.0
+ max_rot_vel: 1.57
diff --git a/unilabos/device_mesh/devices/toyo_xyz/config/ros2_controllers.yaml b/unilabos/device_mesh/devices/toyo_xyz/config/ros2_controllers.yaml
new file mode 100644
index 0000000..1d1a552
--- /dev/null
+++ b/unilabos/device_mesh/devices/toyo_xyz/config/ros2_controllers.yaml
@@ -0,0 +1,34 @@
+# This config file is used by ros2_control
+controller_manager:
+
+ ros__parameters:
+ update_rate: 100 # Hz
+
+ joint_state_broadcaster:
+ type: joint_state_broadcaster/JointStateBroadcaster
+ # action_ns: $(var device_id)
+ toyo_xyz_controller:
+ type: joint_trajectory_controller/JointTrajectoryController
+
+# joint_state_broadcaster:
+# ros__parameters: {}
+
+toyo_xyz_controller:
+ ros__parameters:
+ joints:
+ - slider1_joint
+ - slider2_joint
+ - slider3_joint
+ command_interfaces:
+ - position
+ state_interfaces:
+ - position
+ - velocity
+ allow_partial_joints_goal: false
+ open_loop_control: true
+ allow_integration_in_goal_trajectories: true
+ action_monitor_rate: 20.0
+ # goal_time: 0.0
+ # constraints:
+ # stopped_velocity_tolerance: 0.01
+ # goal_time: 0.0
\ No newline at end of file
diff --git a/unilabos/device_mesh/devices/toyo_xyz/joint_config.json b/unilabos/device_mesh/devices/toyo_xyz/joint_config.json
new file mode 100644
index 0000000..26bda26
--- /dev/null
+++ b/unilabos/device_mesh/devices/toyo_xyz/joint_config.json
@@ -0,0 +1,14 @@
+{
+ "slider1_joint": {
+ "child":"slider1_link",
+ "axis" : "x"
+ },
+ "slider2_joint": {
+ "child":"slider2_link",
+ "axis" : "x"
+ },
+ "slider3_joint": {
+ "child":"slider3_link",
+ "axis" : "x"
+ }
+}
\ No newline at end of file
diff --git a/unilabos/device_mesh/devices/toyo_xyz/macro_device.xacro b/unilabos/device_mesh/devices/toyo_xyz/macro_device.xacro
new file mode 100644
index 0000000..5694c35
--- /dev/null
+++ b/unilabos/device_mesh/devices/toyo_xyz/macro_device.xacro
@@ -0,0 +1,465 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/base2_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/base2_link.STL
new file mode 100755
index 0000000..ded0641
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/base2_link.STL differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/base2_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/base2_link.fbx
new file mode 100644
index 0000000..a278cc6
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/base2_link.fbx differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/base3_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/base3_link.STL
new file mode 100755
index 0000000..d1dba51
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/base3_link.STL differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/base3_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/base3_link.fbx
new file mode 100644
index 0000000..8c28d39
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/base3_link.fbx differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/base_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/base_link.STL
new file mode 100755
index 0000000..24205e5
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/base_link.STL differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/base_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/base_link.fbx
new file mode 100644
index 0000000..5a24339
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/base_link.fbx differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/chain_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/chain_link.STL
new file mode 100755
index 0000000..fcbfdce
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/chain_link.STL differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/chain_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/chain_link.fbx
new file mode 100644
index 0000000..8bd35db
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/chain_link.fbx differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/end2_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/end2_link.STL
new file mode 100755
index 0000000..1b72d5d
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/end2_link.STL differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/end2_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/end2_link.fbx
new file mode 100644
index 0000000..0107961
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/end2_link.fbx differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/end3_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/end3_link.STL
new file mode 100755
index 0000000..ce0dd9f
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/end3_link.STL differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/end3_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/end3_link.fbx
new file mode 100644
index 0000000..f0e55b5
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/end3_link.fbx differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/end_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/end_link.STL
new file mode 100755
index 0000000..6f5e504
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/end_link.STL differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/end_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/end_link.fbx
new file mode 100644
index 0000000..4ba363c
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/end_link.fbx differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/fixed_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/fixed_link.STL
new file mode 100755
index 0000000..7a064cc
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/fixed_link.STL differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/fixed_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/fixed_link.fbx
new file mode 100644
index 0000000..ea46d65
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/fixed_link.fbx differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/length1_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/length1_link.STL
new file mode 100755
index 0000000..9eb85cd
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/length1_link.STL differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/length1_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/length1_link.fbx
new file mode 100644
index 0000000..5375fce
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/length1_link.fbx differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/length2_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/length2_link.STL
new file mode 100755
index 0000000..3ffad0f
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/length2_link.STL differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/length2_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/length2_link.fbx
new file mode 100644
index 0000000..f94c5a6
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/length2_link.fbx differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/length3_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/length3_link.STL
new file mode 100755
index 0000000..1afcdd2
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/length3_link.STL differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/length3_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/length3_link.fbx
new file mode 100644
index 0000000..a812b4c
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/length3_link.fbx differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/slider1_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/slider1_link.STL
new file mode 100755
index 0000000..9ef91e2
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/slider1_link.STL differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/slider1_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/slider1_link.fbx
new file mode 100644
index 0000000..e2a7c86
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/slider1_link.fbx differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/slider2_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/slider2_link.STL
new file mode 100755
index 0000000..abd8c56
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/slider2_link.STL differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/slider2_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/slider2_link.fbx
new file mode 100644
index 0000000..a46df10
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/slider2_link.fbx differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/slider3_link.STL b/unilabos/device_mesh/devices/toyo_xyz/meshes/slider3_link.STL
new file mode 100755
index 0000000..a0bfb16
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/slider3_link.STL differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/meshes/slider3_link.fbx b/unilabos/device_mesh/devices/toyo_xyz/meshes/slider3_link.fbx
new file mode 100644
index 0000000..6cec964
Binary files /dev/null and b/unilabos/device_mesh/devices/toyo_xyz/meshes/slider3_link.fbx differ
diff --git a/unilabos/device_mesh/devices/toyo_xyz/param_config.json b/unilabos/device_mesh/devices/toyo_xyz/param_config.json
new file mode 100644
index 0000000..457332b
--- /dev/null
+++ b/unilabos/device_mesh/devices/toyo_xyz/param_config.json
@@ -0,0 +1,20 @@
+{
+ "private_param":
+ {
+ "min_d1": 0.01 ,
+ "max_d1": 0.01 ,
+ "slider_d1": 0.135,
+ "min_d2": 0.01 ,
+ "max_d2": 0.01 ,
+ "slider_d2": 0.116,
+ "min_d3": 0.01 ,
+ "max_d3": 0.01 ,
+ "slider_d3": 0.09
+ },
+ "public_param":
+ {
+ "length1" :0.5,
+ "length2" :0.2,
+ "length3" :0.2
+ }
+}
\ No newline at end of file
diff --git a/unilabos/device_mesh/resource_visalization.py b/unilabos/device_mesh/resource_visalization.py
index b840789..cea7afc 100644
--- a/unilabos/device_mesh/resource_visalization.py
+++ b/unilabos/device_mesh/resource_visalization.py
@@ -1,13 +1,38 @@
+import json
import os
from pathlib import Path
+import re
+
+import yaml
from launch import LaunchService
from launch import LaunchDescription
from launch_ros.actions import Node as nd
import xacro
from lxml import etree
-
+from launch_param_builder import load_yaml
+from launch_ros.parameter_descriptions import ParameterFile
from unilabos.registry.registry import lab_registry
+from ament_index_python.packages import get_package_share_directory
+def get_pattern_matches(folder, pattern):
+ """Given all the files in the folder, find those that match the pattern.
+
+ If there are groups defined, the groups are returned. Otherwise the path to the matches are returned.
+ """
+ matches = []
+ if not folder.exists():
+ return matches
+ for child in folder.iterdir():
+ if not child.is_file():
+ continue
+ m = pattern.search(child.name)
+ if m:
+ groups = m.groups()
+ if groups:
+ matches.append(groups[0])
+ else:
+ matches.append(child)
+ return matches
class ResourceVisualization:
def __init__(self, device: dict, resource: dict, enable_rviz: bool = True):
@@ -31,9 +56,8 @@ class ResourceVisualization:
self.enable_rviz = enable_rviz
registry = lab_registry
- self.srdf_str = '''
-
-
+ self.srdf_str = '''
+
'''
@@ -43,23 +67,46 @@ class ResourceVisualization:
'''
self.root = etree.fromstring(self.robot_state_str)
+ self.root_srdf = etree.fromstring(self.srdf_str)
xacro_uri = self.root.nsmap["xacro"]
+ self.moveit_nodes = {}
+ self.moveit_nodes_kinematics = {}
+ self.moveit_controllers_yaml = {
+ "moveit_controller_manager": "moveit_simple_controller_manager/MoveItSimpleControllerManager",
+ "moveit_simple_controller_manager": {
+ "controller_names": []
+ }
+ }
+ self.ros2_controllers_yaml = {
+ "controller_manager": {
+ "ros__parameters": {
+ "update_rate": 100,
+ "joint_state_broadcaster": {
+ "type": "joint_state_broadcaster/JointStateBroadcaster",
+ }
+ }
+ }
+ }
+
# 遍历设备节点
for node in device.values():
- if node['type'] == 'device' and node['class'] != '':
- device_class = node['class']
- # 检查设备类型是否在注册表中
- if device_class not in registry.device_type_registry.keys():
- raise ValueError(f"设备类型 {device_class} 未在注册表中注册")
- elif node['type'] in self.resource_type:
- # print(registry.resource_type_registry)
- resource_class = node['class']
- if resource_class not in registry.resource_type_registry.keys():
- raise ValueError(f"资源类型 {resource_class} 未在注册表中注册")
- elif "model" in registry.resource_type_registry[resource_class].keys():
- model_config = registry.resource_type_registry[resource_class]['model']
+ if node['type'] in self.resource_type or (node['type'] == 'device' and node['class'] != ''):
+ model_config = {}
+ if node['type'] in self.resource_type:
+ resource_class = node['class']
+ if resource_class not in registry.resource_type_registry.keys():
+ raise ValueError(f"资源类型 {resource_class} 未在注册表中注册")
+ elif "model" in registry.resource_type_registry[resource_class].keys():
+ model_config = registry.resource_type_registry[resource_class]['model']
+ elif node['type'] == 'device' and node['class'] != '':
+ device_class = node['class']
+ if device_class not in registry.device_type_registry.keys():
+ raise ValueError(f"设备类型 {device_class} 未在注册表中注册")
+ elif "model" in registry.device_type_registry[device_class].keys():
+ model_config = registry.device_type_registry[device_class]['model']
+ if model_config:
if model_config['type'] == 'resource':
self.resource_model[node['id']] = {
'mesh': f"{str(self.mesh_path)}/resources/{model_config['mesh']}",
@@ -71,18 +118,45 @@ class ResourceVisualization:
'mesh_tf': model_config['children_mesh_tf']
}
elif model_config['type'] == 'device':
+
new_include = etree.SubElement(self.root, f"{{{xacro_uri}}}include")
new_include.set("filename", f"{str(self.mesh_path)}/devices/{model_config['mesh']}/macro_device.xacro")
new_dev = etree.SubElement(self.root, f"{{{xacro_uri}}}{model_config['mesh']}")
new_dev.set("parent_link", "world")
new_dev.set("mesh_path", str(self.mesh_path))
new_dev.set("device_name", node["id"]+"_")
- new_dev.set("station_name", node["parent"]+'_')
+ # if node["parent"] is not None:
+ # new_dev.set("station_name", node["parent"]+'_')
+
+ print('o'*20)
+ node["parent"]
+ node["id"]
+ print('o'*20)
new_dev.set("x",str(float(node["position"]["x"])/1000))
new_dev.set("y",str(float(node["position"]["y"])/1000))
new_dev.set("z",str(float(node["position"]["z"])/1000))
if "rotation" in node["config"]:
- new_dev.set("r",str(float(node["config"]["rotation"]["z"])/1000))
+ new_dev.set("rx",str(float(node["config"]["rotation"]["x"])))
+ new_dev.set("ry",str(float(node["config"]["rotation"]["y"])))
+ new_dev.set("r",str(float(node["config"]["rotation"]["z"])))
+ if "device_config" in node["config"]:
+ for key, value in node["config"]["device_config"].items():
+ new_dev.set(key, str(float(value)))
+
+ # 添加ros2_controller
+ if node['class'].startswith('moveit.'):
+ new_include_controller = etree.SubElement(self.root, f"{{{xacro_uri}}}include")
+ new_include_controller.set("filename", f"{str(self.mesh_path)}/devices/{model_config['mesh']}/config/macro.ros2_control.xacro")
+ new_controller = etree.SubElement(self.root, f"{{{xacro_uri}}}{model_config['mesh']}_ros2_control")
+ new_controller.set("device_name", node["id"]+"_")
+ new_controller.set("mesh_path", str(self.mesh_path))
+
+ # 添加moveit的srdf
+ new_include_srdf = etree.SubElement(self.root_srdf, f"{{{xacro_uri}}}include")
+ new_include_srdf.set("filename", f"{str(self.mesh_path)}/devices/{model_config['mesh']}/config/macro.srdf.xacro")
+ new_srdf = etree.SubElement(self.root_srdf, f"{{{xacro_uri}}}{model_config['mesh']}_srdf")
+ new_srdf.set("device_name", node["id"]+"_")
+ self.moveit_nodes[node["id"]] = model_config['mesh']
else:
print("错误的注册表类型!")
re = etree.tostring(self.root, encoding="unicode")
@@ -90,8 +164,37 @@ class ResourceVisualization:
xacro.process_doc(doc)
self.urdf_str = doc.toxml()
+ re_srdf = etree.tostring(self.root_srdf, encoding="unicode")
+ doc_srdf = xacro.parse(re_srdf)
+ xacro.process_doc(doc_srdf)
+ self.urdf_str_srdf = doc_srdf.toxml()
+ if self.moveit_nodes:
+ self.moveit_init()
- def create_launch_description(self, urdf_str: str) -> LaunchDescription:
+ def moveit_init(self):
+
+ for name, config in self.moveit_nodes.items():
+ controller_dict = yaml.safe_load(open(f"{str(self.mesh_path)}/devices/{config}/config/ros2_controllers.yaml", "r"))
+ moveit_dict = yaml.safe_load(open(f"{str(self.mesh_path)}/devices/{config}/config/moveit_controllers.yaml", "r"))
+ kinematics_dict = yaml.safe_load(open(f"{str(self.mesh_path)}/devices/{config}/config/kinematics.yaml", "r"))
+
+ for key_kinematics, value_kinematics in kinematics_dict.items():
+ self.moveit_nodes_kinematics[f'{name}_{key_kinematics}'] = value_kinematics
+
+ for key, value in controller_dict['controller_manager']['ros__parameters'].items():
+ if key == 'update_rate' or key == 'joint_state_broadcaster':
+ continue
+ self.ros2_controllers_yaml['controller_manager']['ros__parameters'][f"{name}_{key}"] = value
+ controller_dict[key]['ros__parameters']['joints'] = [f"{name}_{joint}" for joint in controller_dict[key]['ros__parameters']['joints']]
+ self.ros2_controllers_yaml[f"{name}_{key}"] = controller_dict[key]
+
+ for controller_name in moveit_dict['moveit_simple_controller_manager']['controller_names']:
+ self.moveit_controllers_yaml['moveit_simple_controller_manager']['controller_names'].append(f"{name}_{controller_name}")
+ moveit_dict['moveit_simple_controller_manager'][controller_name]['joints'] = [f"{name}_{joint}" for joint in moveit_dict['moveit_simple_controller_manager'][controller_name]['joints']]
+ self.moveit_controllers_yaml['moveit_simple_controller_manager'][f"{name}_{controller_name}"] = moveit_dict['moveit_simple_controller_manager'][controller_name]
+
+
+ def create_launch_description(self) -> LaunchDescription:
"""
创建launch描述,包含robot_state_publisher和move_group节点
@@ -101,10 +204,93 @@ class ResourceVisualization:
Returns:
LaunchDescription: launch描述对象
"""
+ moveit_configs_utils_path = Path(get_package_share_directory("moveit_configs_utils"))
+ default_folder = moveit_configs_utils_path / "default_configs"
+ planning_pattern = re.compile("^(.*)_planning.yaml$")
+ pipelines = []
-
+ for pipeline in get_pattern_matches(default_folder, planning_pattern):
+ if pipeline not in pipelines:
+ pipelines.append(pipeline)
+
+ if "ompl" in pipelines:
+ default_planning_pipeline = "ompl"
+ else:
+ default_planning_pipeline = pipelines[0]
+
+ planning_pipelines = {
+ "planning_pipelines": pipelines,
+ "default_planning_pipeline": default_planning_pipeline,
+ }
+
+ for pipeline in pipelines:
+ planning_pipelines[pipeline] = load_yaml(
+ default_folder / f"{pipeline}_planning.yaml"
+ )
+
+ if "ompl" in planning_pipelines:
+ ompl_config = planning_pipelines["ompl"]
+ if "planner_configs" not in ompl_config:
+ ompl_config.update(load_yaml(default_folder / "ompl_defaults.yaml"))
+
+ yaml.safe_dump(self.ros2_controllers_yaml, open(f"{str(self.mesh_path)}/ros2_controllers.yaml", "w"))
+
+ robot_description_planning = {
+ "default_velocity_scaling_factor": 0.1,
+ "default_acceleration_scaling_factor": 0.1,
+ "cartesian_limits": {
+ "max_trans_vel": 1.0,
+ "max_trans_acc": 2.25,
+ "max_trans_dec": -5.0,
+ "max_rot_vel": 1.57
+ }
+ }
# 解析URDF文件
- robot_description = urdf_str
+ robot_description = self.urdf_str
+ urdf_str_srdf = self.urdf_str_srdf
+
+ kinematics_dict = self.moveit_nodes_kinematics
+
+ if self.moveit_nodes:
+ controllers = []
+ ros2_controllers = ParameterFile(f"{str(self.mesh_path)}/ros2_controllers.yaml", allow_substs=True)
+
+ controllers.append(
+ nd(
+ package="controller_manager",
+ executable="ros2_control_node",
+ output='screen',
+ parameters=[
+ {"robot_description": robot_description},
+ ros2_controllers,
+ ]
+ )
+ )
+ for controller in self.moveit_controllers_yaml['moveit_simple_controller_manager']['controller_names']:
+ controllers.append(
+ nd(
+ package="controller_manager",
+ executable="spawner",
+ arguments=[f"{controller}", "--controller-manager", f"controller_manager"],
+ output="screen",
+ )
+ )
+ controllers.append(
+ nd(
+ package="controller_manager",
+ executable="spawner",
+ arguments=["joint_state_broadcaster", "--controller-manager", f"controller_manager"],
+ output="screen",
+ )
+ )
+ for i in controllers:
+ self.launch_description.add_action(i)
+ else:
+ ros2_controllers = None
+
+
+
+
# 创建robot_state_publisher节点
robot_state_publisher = nd(
@@ -115,23 +301,21 @@ class ResourceVisualization:
parameters=[{
'robot_description': robot_description,
'use_sim_time': False
- }]
+ },
+ # kinematics_dict
+ ]
)
- # joint_state_publisher_node = nd(
- # package='joint_state_publisher_gui', # 或 joint_state_publisher
- # executable='joint_state_publisher_gui',
- # name='joint_state_publisher',
- # output='screen'
- # )
# 创建move_group节点
move_group = nd(
package='moveit_ros_move_group',
executable='move_group',
output='screen',
parameters=[{
+ 'allow_trajectory_execution': True,
'robot_description': robot_description,
- 'robot_description_semantic': self.srdf_str,
+ 'robot_description_semantic': urdf_str_srdf,
+ 'robot_description_kinematics': kinematics_dict,
'capabilities': '',
'disable_capabilities': '',
'monitor_dynamics': False,
@@ -141,7 +325,13 @@ class ResourceVisualization:
'publish_geometry_updates': True,
'publish_state_updates': True,
'publish_transforms_updates': True,
- }]
+ # 'robot_description_planning': robot_description_planning,
+ },
+ self.moveit_controllers_yaml,
+ # ompl_planning_pipeline_config,
+ robot_description_planning,
+ planning_pipelines,
+ ]
)
# 将节点添加到launch描述中
@@ -156,7 +346,14 @@ class ResourceVisualization:
executable='rviz2',
name='rviz2',
arguments=['-d', f"{str(self.mesh_path)}/view_robot.rviz"],
- output='screen'
+ output='screen',
+ parameters=[
+ {'robot_description_kinematics': kinematics_dict,
+ },
+ robot_description_planning,
+ planning_pipelines,
+
+ ]
)
self.launch_description.add_action(rviz_node)
@@ -169,6 +366,11 @@ class ResourceVisualization:
Args:
urdf_str: URDF文件路径
"""
- launch_description = self.create_launch_description(self.urdf_str)
+ launch_description = self.create_launch_description()
+ # print('--------------------------------')
+ # print(self.moveit_controllers_yaml)
+ # print('--------------------------------')
+ # print(self.urdf_str)
+ # print('--------------------------------')
self.launch_service.include_launch_description(launch_description)
self.launch_service.run()
\ No newline at end of file
diff --git a/unilabos/device_mesh/ros2_controllers.yaml b/unilabos/device_mesh/ros2_controllers.yaml
new file mode 100644
index 0000000..e54c64c
--- /dev/null
+++ b/unilabos/device_mesh/ros2_controllers.yaml
@@ -0,0 +1,31 @@
+benyao_arm_controller:
+ ros__parameters:
+ command_interfaces:
+ - position
+ joints:
+ - benyao_arm_base_joint
+ - benyao_arm_link_1_joint
+ - benyao_arm_link_2_joint
+ - benyao_arm_link_3_joint
+ - benyao_gripper_base_joint
+ state_interfaces:
+ - position
+ - velocity
+benyao_gripper_controller:
+ ros__parameters:
+ command_interfaces:
+ - position
+ joints:
+ - benyao_gripper_right_joint
+ state_interfaces:
+ - position
+ - velocity
+controller_manager:
+ ros__parameters:
+ benyao_arm_controller:
+ type: joint_trajectory_controller/JointTrajectoryController
+ benyao_gripper_controller:
+ type: joint_trajectory_controller/JointTrajectoryController
+ joint_state_broadcaster:
+ type: joint_state_broadcaster/JointStateBroadcaster
+ update_rate: 100
diff --git a/unilabos/device_mesh/view_robot.rviz b/unilabos/device_mesh/view_robot.rviz
index 64f6b35..368a2ed 100644
--- a/unilabos/device_mesh/view_robot.rviz
+++ b/unilabos/device_mesh/view_robot.rviz
@@ -1,23 +1,15 @@
Panels:
- Class: rviz_common/Displays
- Help Height: 138
+ Help Height: 0
Name: Displays
Property Tree Widget:
Expanded:
- - /Global Options1
- - /TF1
- /TF1/Tree1
- - /RobotModel1
- - /PlanningScene1
- - /PlanningScene1/Scene Geometry1
- - /RobotState1
- - /RobotState1/Links1
- - /MotionPlanning1
- /MotionPlanning1/Scene Geometry1
- /MotionPlanning1/Scene Robot1
- /MotionPlanning1/Planning Request1
- Splitter Ratio: 0.5
- Tree Height: 345
+ Splitter Ratio: 0.5016146302223206
+ Tree Height: 1112
- Class: rviz_common/Selection
Name: Selection
- Class: rviz_common/Tool Properties
@@ -93,7 +85,7 @@ Visualization Manager:
Value: false
Visual Enabled: true
- Class: moveit_rviz_plugin/PlanningScene
- Enabled: false
+ Enabled: true
Move Group Namespace: ""
Name: PlanningScene
Planning Scene Topic: /monitored_planning_scene
@@ -104,7 +96,7 @@ Visualization Manager:
Scene Display Time: 0.009999999776482582
Show Scene Geometry: true
Voxel Coloring: Z-Axis
- Voxel Rendering: Occupied Voxels
+ Voxel Rendering: Disabled
Scene Robot:
Attached Body Color: 150; 50; 150
Links:
@@ -113,10 +105,108 @@ Visualization Manager:
Expand Link Details: false
Expand Tree: false
Link Tree Style: Links in Alphabetic Order
+ PLR_STATION_deck_device_link:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ PLR_STATION_deck_first_link:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ PLR_STATION_deck_fourth_link:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ PLR_STATION_deck_main_link:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ PLR_STATION_deck_second_link:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ PLR_STATION_deck_socketTypeGenericSbsFootprint:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ PLR_STATION_deck_socketTypeHEPAModule:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ PLR_STATION_deck_third_link:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ benyao_arm_base:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ benyao_arm_link_1:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ benyao_arm_link_2:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ benyao_arm_link_3:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ benyao_arm_slideway:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ benyao_device_link:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ benyao_gripper_base:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ benyao_gripper_left:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ benyao_gripper_right:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ hotel_base_link:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ hotel_device_link:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ hotel_socketTypeGenericSbsFootprint:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ world:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
Robot Alpha: 1
Show Robot Collision: false
Show Robot Visual: false
- Value: false
+ Value: true
- Attached Body Color: 150; 50; 150
Class: moveit_rviz_plugin/RobotState
Collision Enabled: false
@@ -203,6 +293,63 @@ Visualization Manager:
Show Axes: false
Show Trail: false
Value: true
+ benyao_arm_base:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ benyao_arm_link_1:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ benyao_arm_link_2:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ benyao_arm_link_3:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ benyao_arm_slideway:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ benyao_device_link:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ benyao_gripper_base:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ benyao_gripper_left:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ benyao_gripper_right:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ hotel_base_link:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ hotel_device_link:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ hotel_socketTypeGenericSbsFootprint:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
world:
Alpha: 1
Show Axes: false
@@ -230,7 +377,7 @@ Visualization Manager:
Goal State Color: 250; 128; 0
Interactive Marker Size: 0
Joint Violation Color: 255; 0; 255
- Planning Group: ""
+ Planning Group: benyao_arm
Query Goal State: false
Query Start State: false
Show Workspace: false
@@ -242,9 +389,9 @@ Visualization Manager:
Scene Alpha: 0.8999999761581421
Scene Color: 50; 230; 50
Scene Display Time: 0.009999999776482582
- Show Scene Geometry: true
- Voxel Coloring: Z-Axis
- Voxel Rendering: Occupied Voxels
+ Show Scene Geometry: false
+ Voxel Coloring: Cell Probability
+ Voxel Rendering: All Voxels
Scene Robot:
Attached Body Color: 150; 50; 150
Links:
@@ -290,6 +437,63 @@ Visualization Manager:
Show Axes: false
Show Trail: false
Value: true
+ benyao_arm_base:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ benyao_arm_link_1:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ benyao_arm_link_2:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ benyao_arm_link_3:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ benyao_arm_slideway:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ benyao_device_link:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ benyao_gripper_base:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ benyao_gripper_left:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ benyao_gripper_right:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ hotel_base_link:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ Value: true
+ hotel_device_link:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
+ hotel_socketTypeGenericSbsFootprint:
+ Alpha: 1
+ Show Axes: false
+ Show Trail: false
world:
Alpha: 1
Show Axes: false
@@ -345,43 +549,43 @@ Visualization Manager:
Views:
Current:
Class: rviz_default_plugins/Orbit
- Distance: 1.0284695625305176
+ Distance: 2.622864246368408
Enable Stereo Rendering:
Stereo Eye Separation: 0.05999999865889549
Stereo Focal Distance: 1
Swap Stereo Eyes: false
Value: false
Focal Point:
- X: 0.29730814695358276
- Y: 0.21228469908237457
- Z: 0.20008830726146698
+ X: -0.2880733013153076
+ Y: -0.16004444658756256
+ Z: -0.16730672121047974
Focal Shape Fixed Size: true
Focal Shape Size: 0.05000000074505806
Invert Z Axis: false
Name: Current View
Near Clip Distance: 0.009999999776482582
- Pitch: 0.38979560136795044
+ Pitch: 0.48479583859443665
Target Frame:
Value: Orbit (rviz)
- Yaw: 0.06074193865060806
+ Yaw: 0.042561568319797516
Saved: ~
Window Geometry:
Displays:
collapsed: false
- Height: 1656
+ Height: 2032
Hide Left Dock: false
Hide Right Dock: true
MotionPlanning:
collapsed: false
MotionPlanning - Trajectory Slider:
collapsed: false
- QMainWindow State: 000000ff00000000fd0000000400000000000003a3000005dcfc020000000bfb0000001200530065006c0065006300740069006f006e00000001e10000009b000000b000fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000006e000002510000018200fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb000000280020002d0020005400720061006a006500630074006f0072007900200053006c00690064006500720000000000ffffffff0000000000000000fb00000044004d006f00740069006f006e0050006c0061006e006e0069006e00670020002d0020005400720061006a006500630074006f0072007900200053006c00690064006500720000000000ffffffff0000007a00fffffffb0000001c004d006f00740069006f006e0050006c0061006e006e0069006e006701000002cb0000037f000002b800ffffff000000010000010f00000387fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073000000003b000003870000013200fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004420000003efc0100000002fb0000000800540069006d00650100000000000004420000000000000000fb0000000800540069006d0065010000000000000450000000000000000000000627000005dc00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000
+ QMainWindow State: 000000ff00000000fd0000000400000000000003a30000079bfc020000000bfb0000001200530065006c0065006300740069006f006e00000001e10000009b000000b000fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c0061007900730100000027000004c60000018200fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb000000280020002d0020005400720061006a006500630074006f0072007900200053006c00690064006500720000000000ffffffff0000000000000000fb00000044004d006f00740069006f006e0050006c0061006e006e0069006e00670020002d0020005400720061006a006500630074006f0072007900200053006c00690064006500720000000000ffffffff0000002600000026fb0000001c004d006f00740069006f006e0050006c0061006e006e0069006e006701000004f9000002c9000002b800ffffff000000010000010f00000387fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073000000003b000003870000013200fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004420000003efc0100000002fb0000000800540069006d00650100000000000004420000000000000000fb0000000800540069006d0065010000000000000450000000000000000000000bc50000079b00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730000000000ffffffff0000000000000000
Selection:
collapsed: false
Tool Properties:
collapsed: false
Views:
collapsed: true
- Width: 2518
- X: 385
- Y: 120
+ Width: 3956
+ X: 140
+ Y: 54
diff --git a/unilabos/devices/liquid_handling/complete_biomek_protocol.json b/unilabos/devices/liquid_handling/complete_biomek_protocol.json
new file mode 100644
index 0000000..2c0e95f
--- /dev/null
+++ b/unilabos/devices/liquid_handling/complete_biomek_protocol.json
@@ -0,0 +1,3760 @@
+{
+ "meta": {
+ "name": "DNA纯化完整流程",
+ "description": "使用磁珠进行DNA纯化的完整自动化流程",
+ "version": "1.0",
+ "author": "Biomek系统",
+ "date": "2024-01-01",
+ "type": "DNA_purification"
+ },
+ "labwares": [
+ {
+ "Tips": {
+ "Class": "TipClasses\\T230",
+ "Contents": [],
+ "_RT_Contents": [],
+ "Used": false,
+ "RT_Used": false,
+ "Dirty": false,
+ "RT_Dirty": false,
+ "MaxVolumeUsed": 0.0,
+ "RT_MaxVolumeUsed": 0.0
+ },
+ "RT_Tips": {
+ "Class": "TipClasses\\T230",
+ "Contents": [],
+ "_RT_Contents": [],
+ "Used": false,
+ "RT_Used": false,
+ "Dirty": false,
+ "RT_Dirty": false,
+ "MaxVolumeUsed": 0.0,
+ "RT_MaxVolumeUsed": 0.0
+ },
+ "Properties": {},
+ "Known": false,
+ "Class": "LabwareClasses\\BC230",
+ "DataSets": {
+ "Volume": {}
+ },
+ "RuntimeDataSets": {
+ "Volume": {}
+ },
+ "Name": "Tip Rack BC230 on TL1",
+ "Position": "TL1"
+ },
+ {
+ "Tips": {
+ "Class": "TipClasses\\T230",
+ "Contents": [],
+ "_RT_Contents": [],
+ "Used": false,
+ "RT_Used": false,
+ "Dirty": false,
+ "RT_Dirty": false,
+ "MaxVolumeUsed": 0.0,
+ "RT_MaxVolumeUsed": 0.0
+ },
+ "RT_Tips": {
+ "Class": "TipClasses\\T230",
+ "Contents": [],
+ "_RT_Contents": [],
+ "Used": false,
+ "RT_Used": false,
+ "Dirty": false,
+ "RT_Dirty": false,
+ "MaxVolumeUsed": 0.0,
+ "RT_MaxVolumeUsed": 0.0
+ },
+ "Properties": {},
+ "Known": false,
+ "Class": "LabwareClasses\\BC230",
+ "DataSets": {
+ "Volume": {}
+ },
+ "RuntimeDataSets": {
+ "Volume": {}
+ },
+ "Name": "Tip Rack BC230 on TL2",
+ "Position": "TL2"
+ },
+ {
+ "Tips": {
+ "Class": "TipClasses\\T230",
+ "Contents": [],
+ "_RT_Contents": [],
+ "Used": false,
+ "RT_Used": false,
+ "Dirty": false,
+ "RT_Dirty": false,
+ "MaxVolumeUsed": 0.0,
+ "RT_MaxVolumeUsed": 0.0
+ },
+ "RT_Tips": {
+ "Class": "TipClasses\\T230",
+ "Contents": [],
+ "_RT_Contents": [],
+ "Used": false,
+ "RT_Used": false,
+ "Dirty": false,
+ "RT_Dirty": false,
+ "MaxVolumeUsed": 0.0,
+ "RT_MaxVolumeUsed": 0.0
+ },
+ "Properties": {},
+ "Known": false,
+ "Class": "LabwareClasses\\BC230",
+ "DataSets": {
+ "Volume": {}
+ },
+ "RuntimeDataSets": {
+ "Volume": {}
+ },
+ "Name": "Tip Rack BC230 on TL3",
+ "Position": "TL3"
+ },
+ {
+ "Tips": {
+ "Class": "TipClasses\\T230",
+ "Contents": [],
+ "_RT_Contents": [],
+ "Used": false,
+ "RT_Used": false,
+ "Dirty": false,
+ "RT_Dirty": false,
+ "MaxVolumeUsed": 0.0,
+ "RT_MaxVolumeUsed": 0.0
+ },
+ "RT_Tips": {
+ "Class": "TipClasses\\T230",
+ "Contents": [],
+ "_RT_Contents": [],
+ "Used": false,
+ "RT_Used": false,
+ "Dirty": false,
+ "RT_Dirty": false,
+ "MaxVolumeUsed": 0.0,
+ "RT_MaxVolumeUsed": 0.0
+ },
+ "Properties": {},
+ "Known": false,
+ "Class": "LabwareClasses\\BC230",
+ "DataSets": {
+ "Volume": {}
+ },
+ "RuntimeDataSets": {
+ "Volume": {}
+ },
+ "Name": "Tip Rack BC230 on TL4",
+ "Position": "TL4"
+ },
+ {
+ "Tips": {
+ "Class": "TipClasses\\T230",
+ "Contents": [],
+ "_RT_Contents": [],
+ "Used": false,
+ "RT_Used": false,
+ "Dirty": false,
+ "RT_Dirty": false,
+ "MaxVolumeUsed": 0.0,
+ "RT_MaxVolumeUsed": 0.0
+ },
+ "RT_Tips": {
+ "Class": "TipClasses\\T230",
+ "Contents": [],
+ "_RT_Contents": [],
+ "Used": false,
+ "RT_Used": false,
+ "Dirty": false,
+ "RT_Dirty": false,
+ "MaxVolumeUsed": 0.0,
+ "RT_MaxVolumeUsed": 0.0
+ },
+ "Properties": {},
+ "Known": false,
+ "Class": "LabwareClasses\\BC230",
+ "DataSets": {
+ "Volume": {}
+ },
+ "RuntimeDataSets": {
+ "Volume": {}
+ },
+ "Name": "Tip Rack BC230 on TL5",
+ "Position": "TL5"
+ },
+ {
+ "Tips": {
+ "Class": "TipClasses\\T230",
+ "Contents": [],
+ "_RT_Contents": [],
+ "Used": false,
+ "RT_Used": false,
+ "Dirty": false,
+ "RT_Dirty": false,
+ "MaxVolumeUsed": 0.0,
+ "RT_MaxVolumeUsed": 0.0
+ },
+ "RT_Tips": {
+ "Class": "TipClasses\\T230",
+ "Contents": [],
+ "_RT_Contents": [],
+ "Used": false,
+ "RT_Used": false,
+ "Dirty": false,
+ "RT_Dirty": false,
+ "MaxVolumeUsed": 0.0,
+ "RT_MaxVolumeUsed": 0.0
+ },
+ "Properties": {},
+ "Known": false,
+ "Class": "LabwareClasses\\BC230",
+ "DataSets": {
+ "Volume": {}
+ },
+ "RuntimeDataSets": {
+ "Volume": {}
+ },
+ "Name": "Tip Rack BC230 on P5",
+ "Position": "P5"
+ },
+ {
+ "Tips": {
+ "Class": "TipClasses\\T230",
+ "Contents": [],
+ "_RT_Contents": [],
+ "Used": false,
+ "RT_Used": false,
+ "Dirty": false,
+ "RT_Dirty": false,
+ "MaxVolumeUsed": 0.0,
+ "RT_MaxVolumeUsed": 0.0
+ },
+ "RT_Tips": {
+ "Class": "TipClasses\\T230",
+ "Contents": [],
+ "_RT_Contents": [],
+ "Used": false,
+ "RT_Used": false,
+ "Dirty": false,
+ "RT_Dirty": false,
+ "MaxVolumeUsed": 0.0,
+ "RT_MaxVolumeUsed": 0.0
+ },
+ "Properties": {},
+ "Known": false,
+ "Class": "LabwareClasses\\BC230",
+ "DataSets": {
+ "Volume": {}
+ },
+ "RuntimeDataSets": {
+ "Volume": {}
+ },
+ "Name": "Tip Rack BC230 on P6",
+ "Position": "P6"
+ },
+ {
+ "Tips": {
+ "Class": "TipClasses\\T230",
+ "Contents": [],
+ "_RT_Contents": [],
+ "Used": false,
+ "RT_Used": false,
+ "Dirty": false,
+ "RT_Dirty": false,
+ "MaxVolumeUsed": 0.0,
+ "RT_MaxVolumeUsed": 0.0
+ },
+ "RT_Tips": {
+ "Class": "TipClasses\\T230",
+ "Contents": [],
+ "_RT_Contents": [],
+ "Used": false,
+ "RT_Used": false,
+ "Dirty": false,
+ "RT_Dirty": false,
+ "MaxVolumeUsed": 0.0,
+ "RT_MaxVolumeUsed": 0.0
+ },
+ "Properties": {},
+ "Known": false,
+ "Class": "LabwareClasses\\BC230",
+ "DataSets": {
+ "Volume": {}
+ },
+ "RuntimeDataSets": {
+ "Volume": {}
+ },
+ "Name": "Tip Rack BC230 on P15",
+ "Position": "P15"
+ },
+ {
+ "Tips": {
+ "Class": "TipClasses\\T230",
+ "Contents": [],
+ "_RT_Contents": [],
+ "Used": false,
+ "RT_Used": false,
+ "Dirty": false,
+ "RT_Dirty": false,
+ "MaxVolumeUsed": 0.0,
+ "RT_MaxVolumeUsed": 0.0
+ },
+ "RT_Tips": {
+ "Class": "TipClasses\\T230",
+ "Contents": [],
+ "_RT_Contents": [],
+ "Used": false,
+ "RT_Used": false,
+ "Dirty": false,
+ "RT_Dirty": false,
+ "MaxVolumeUsed": 0.0,
+ "RT_MaxVolumeUsed": 0.0
+ },
+ "Properties": {},
+ "Known": false,
+ "Class": "LabwareClasses\\BC230",
+ "DataSets": {
+ "Volume": {}
+ },
+ "RuntimeDataSets": {
+ "Volume": {}
+ },
+ "Name": "Tip Rack BC230 on P16",
+ "Position": "P16"
+ },
+ {
+ "Properties": {
+ "Name": "stock plate on P1",
+ "Device": "",
+ "liquidtype": "master_mix",
+ "BarCode": "",
+ "SenseEveryTime": false
+ },
+ "Known": true,
+ "Class": "LabwareClasses\\nest_12_reservoir_15ml",
+ "DataSets": {
+ "Volume": {}
+ },
+ "RuntimeDataSets": {
+ "Volume": {}
+ },
+ "EvalAmounts": [
+ 10000.0
+ ],
+ "Nominal": false,
+ "EvalLiquids": [
+ "master_mix"
+ ],
+ "Name": "stock plate on P1",
+ "Position": "P1"
+ },
+ {
+ "Properties": {
+ "Name": "stock plate on P2",
+ "Device": "",
+ "liquidtype": "bind beads",
+ "BarCode": "",
+ "SenseEveryTime": false
+ },
+ "Known": true,
+ "Class": "LabwareClasses\\nest_12_reservoir_15ml",
+ "DataSets": {
+ "Volume": {}
+ },
+ "RuntimeDataSets": {
+ "Volume": {}
+ },
+ "EvalAmounts": [
+ 10000.0
+ ],
+ "Nominal": false,
+ "EvalLiquids": [
+ "bind beads"
+ ],
+ "Name": "stock plate on P2",
+ "Position": "P2"
+ },
+ {
+ "Properties": {
+ "Name": "stock plate on P3",
+ "Device": "",
+ "liquidtype": "ethyl alcohol",
+ "BarCode": "",
+ "SenseEveryTime": false
+ },
+ "Known": true,
+ "Class": "LabwareClasses\\nest_12_reservoir_15ml",
+ "DataSets": {
+ "Volume": {}
+ },
+ "RuntimeDataSets": {
+ "Volume": {}
+ },
+ "EvalAmounts": [
+ 10000.0
+ ],
+ "Nominal": false,
+ "EvalLiquids": [
+ "ethyl alcohol"
+ ],
+ "Name": "stock plate on P3",
+ "Position": "P3"
+ },
+ {
+ "Properties": {
+ "Name": "elution buffer on P4",
+ "Device": "",
+ "liquidtype": "elution buffer",
+ "BarCode": "",
+ "SenseEveryTime": false
+ },
+ "Known": true,
+ "Class": "LabwareClasses\\nest_12_reservoir_15ml",
+ "DataSets": {
+ "Volume": {}
+ },
+ "RuntimeDataSets": {
+ "Volume": {}
+ },
+ "EvalAmounts": [
+ 5000.0
+ ],
+ "Nominal": false,
+ "EvalLiquids": [
+ "elution buffer"
+ ],
+ "Name": "elution buffer on P4",
+ "Position": "P4"
+ },
+ {
+ "Properties": {
+ "Name": "working plate on P11",
+ "Device": "",
+ "liquidtype": "Water",
+ "BarCode": "",
+ "SenseEveryTime": false
+ },
+ "Known": true,
+ "Class": "LabwareClasses\\NEST 2ml Deep Well Plate",
+ "DataSets": {
+ "Volume": {}
+ },
+ "RuntimeDataSets": {
+ "Volume": {}
+ },
+ "EvalAmounts": [
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0
+ ],
+ "Nominal": false,
+ "EvalLiquids": [
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water"
+ ],
+ "Name": "working plate on P11",
+ "Position": "P11"
+ },
+ {
+ "Properties": {
+ "Name": "working plate on P13",
+ "Device": "",
+ "liquidtype": "Water",
+ "BarCode": "",
+ "SenseEveryTime": false
+ },
+ "Known": true,
+ "Class": "LabwareClasses\\NEST 2ml Deep Well Plate",
+ "DataSets": {
+ "Volume": {}
+ },
+ "RuntimeDataSets": {
+ "Volume": {}
+ },
+ "EvalAmounts": [
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0,
+ 500.0
+ ],
+ "Nominal": false,
+ "EvalLiquids": [
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water"
+ ],
+ "Name": "working plate on P13",
+ "Position": "P13"
+ },
+ {
+ "Properties": {
+ "Name": "waste on P22",
+ "Device": "",
+ "liquidtype": "Water",
+ "BarCode": "",
+ "SenseEveryTime": false
+ },
+ "Known": true,
+ "Class": "LabwareClasses\\nest_1_reservoir_195ml",
+ "DataSets": {
+ "Volume": {}
+ },
+ "RuntimeDataSets": {
+ "Volume": {}
+ },
+ "EvalAmounts": [
+ 0.0
+ ],
+ "Nominal": false,
+ "EvalLiquids": [
+ "Water"
+ ],
+ "Name": "waste on P22",
+ "Position": "P22"
+ }
+ ],
+ "steps": [
+ {
+ "transfer": {
+ "Span8": false,
+ "Pod": "Pod1",
+ "items": [
+ {
+ "Position": "P12",
+ "Height": -2.0,
+ "Volume": "40",
+ "liquidtype": "Well Contents",
+ "WellsX": 12,
+ "LabwareClass": "Matrix96_750uL",
+ "AutoSelectPrototype": true,
+ "ColsFirst": true,
+ "CustomHeight": false,
+ "DataSetPattern": false,
+ "HeightFrom": 0,
+ "LocalPattern": true,
+ "Operation": "Aspirate",
+ "OverrideHeight": false,
+ "Pattern": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "Prototype": "MC P300 High",
+ "ReferencedPattern": "",
+ "RowsFirst": false,
+ "SectionExpression": "",
+ "SelectionInfo": [
+ 1
+ ],
+ "SetMark": true,
+ "Source": true,
+ "StartAtMark": false,
+ "StartAtSelection": true,
+ "UseExpression": false
+ },
+ {
+ "Position": "P13",
+ "Height": -2.0,
+ "Volume": "40",
+ "liquidtype": "Tip Contents",
+ "WellsX": 12,
+ "LabwareClass": "Matrix96_750uL",
+ "AutoSelectPrototype": true,
+ "ColsFirst": true,
+ "CustomHeight": false,
+ "DataSetPattern": false,
+ "HeightFrom": 0,
+ "LocalPattern": true,
+ "Operation": "Dispense",
+ "OverrideHeight": false,
+ "Pattern": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "Prototype": "MC P300 High",
+ "ReferencedPattern": "",
+ "RowsFirst": false,
+ "SectionExpression": "",
+ "SelectionInfo": [
+ 1
+ ],
+ "SetMark": true,
+ "Source": false,
+ "StartAtMark": false,
+ "StartAtSelection": true,
+ "UseExpression": false
+ }
+ ],
+ "Wash": false,
+ "Dynamic?": true,
+ "AutoSelectActiveWashTechnique": false,
+ "ActiveWashTechnique": "",
+ "ChangeTipsBetweenDests": true,
+ "ChangeTipsBetweenSources": false,
+ "DefaultCaption": "",
+ "UseExpression": false,
+ "LeaveTipsOn": false,
+ "MandrelExpression": "",
+ "Repeats": "1",
+ "RepeatsByVolume": false,
+ "Replicates": "1",
+ "ShowTipHandlingDetails": false,
+ "ShowTransferDetails": true,
+ "Solvent": "Water",
+ "Span8Wash": false,
+ "Span8WashVolume": "2",
+ "Span8WasteVolume": "1",
+ "SplitVolume": false,
+ "SplitVolumeCleaning": false,
+ "Stop": "Destinations",
+ "TipLocation": "BC230",
+ "UseCurrentTips": false,
+ "UseDisposableTips": false,
+ "UseFixedTips": false,
+ "UseJIT": true,
+ "UseMandrelSelection": true,
+ "UseProbes": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "WashCycles": "4",
+ "WashVolume": "110%",
+ "Wizard": false
+ }
+ },
+ {
+ "transfer": {
+ "Span8": false,
+ "Pod": "Pod1",
+ "items": [
+ {
+ "Position": "P12",
+ "Height": -2.0,
+ "Volume": "40",
+ "liquidtype": "Well Contents",
+ "WellsX": 12,
+ "LabwareClass": "Matrix96_750uL",
+ "AutoSelectPrototype": true,
+ "ColsFirst": true,
+ "CustomHeight": false,
+ "DataSetPattern": false,
+ "HeightFrom": 0,
+ "LocalPattern": true,
+ "Operation": "Aspirate",
+ "OverrideHeight": false,
+ "Pattern": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "Prototype": "MC P300 High",
+ "ReferencedPattern": "",
+ "RowsFirst": false,
+ "SectionExpression": "",
+ "SelectionInfo": [
+ 1
+ ],
+ "SetMark": true,
+ "Source": true,
+ "StartAtMark": false,
+ "StartAtSelection": true,
+ "UseExpression": false
+ },
+ {
+ "Position": "P13",
+ "Height": -2.0,
+ "Volume": "40",
+ "liquidtype": "Tip Contents",
+ "WellsX": 12,
+ "LabwareClass": "Matrix96_750uL",
+ "AutoSelectPrototype": true,
+ "ColsFirst": true,
+ "CustomHeight": false,
+ "DataSetPattern": false,
+ "HeightFrom": 0,
+ "LocalPattern": true,
+ "Operation": "Dispense",
+ "OverrideHeight": false,
+ "Pattern": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "Prototype": "MC P300 High",
+ "ReferencedPattern": "",
+ "RowsFirst": false,
+ "SectionExpression": "",
+ "SelectionInfo": [
+ 1
+ ],
+ "SetMark": true,
+ "Source": false,
+ "StartAtMark": false,
+ "StartAtSelection": true,
+ "UseExpression": false
+ }
+ ],
+ "Wash": false,
+ "Dynamic?": true,
+ "AutoSelectActiveWashTechnique": false,
+ "ActiveWashTechnique": "",
+ "ChangeTipsBetweenDests": true,
+ "ChangeTipsBetweenSources": false,
+ "DefaultCaption": "",
+ "UseExpression": false,
+ "LeaveTipsOn": false,
+ "MandrelExpression": "",
+ "Repeats": "1",
+ "RepeatsByVolume": false,
+ "Replicates": "1",
+ "ShowTipHandlingDetails": false,
+ "ShowTransferDetails": true,
+ "Solvent": "Water",
+ "Span8Wash": false,
+ "Span8WashVolume": "2",
+ "Span8WasteVolume": "1",
+ "SplitVolume": false,
+ "SplitVolumeCleaning": false,
+ "Stop": "Destinations",
+ "TipLocation": "BC230",
+ "UseCurrentTips": false,
+ "UseDisposableTips": false,
+ "UseFixedTips": false,
+ "UseJIT": true,
+ "UseMandrelSelection": true,
+ "UseProbes": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "WashCycles": "4",
+ "WashVolume": "110%",
+ "Wizard": false
+ }
+ },
+ {
+ "move": {
+ "Pod": "Pod1",
+ "GripSide": "A1 near",
+ "Source": "P11",
+ "Target": "Orbital1",
+ "LeaveBottomLabware": false
+ }
+ },
+ {
+ "oscillation": {
+ "Device": "OrbitalShaker0",
+ "Parameters": [
+ "800",
+ "2",
+ "300",
+ "CounterClockwise"
+ ],
+ "Command": "Timed Shake"
+ }
+ },
+ {
+ "move": {
+ "Pod": "Pod1",
+ "GripSide": "A1 near",
+ "Source": "Orbital1",
+ "Target": "P11",
+ "LeaveBottomLabware": false
+ }
+ },
+ {
+ "move": {
+ "Pod": "Pod1",
+ "GripSide": "A1 near",
+ "Source": "P11",
+ "Target": "P12",
+ "LeaveBottomLabware": false
+ }
+ },
+ {
+ "incubation": {
+ "Message": "Paused",
+ "Location": "the whole system",
+ "Time": 180,
+ "Mode": "TimedResource"
+ }
+ },
+ {
+ "transfer": {
+ "Span8": false,
+ "Pod": "Pod1",
+ "items": [
+ {
+ "Position": "P12",
+ "Height": -2.0,
+ "Volume": "40",
+ "liquidtype": "Well Contents",
+ "WellsX": 12,
+ "LabwareClass": "Matrix96_750uL",
+ "AutoSelectPrototype": true,
+ "ColsFirst": true,
+ "CustomHeight": false,
+ "DataSetPattern": false,
+ "HeightFrom": 0,
+ "LocalPattern": true,
+ "Operation": "Aspirate",
+ "OverrideHeight": false,
+ "Pattern": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "Prototype": "MC P300 High",
+ "ReferencedPattern": "",
+ "RowsFirst": false,
+ "SectionExpression": "",
+ "SelectionInfo": [
+ 1
+ ],
+ "SetMark": true,
+ "Source": true,
+ "StartAtMark": false,
+ "StartAtSelection": true,
+ "UseExpression": false
+ },
+ {
+ "Position": "P13",
+ "Height": -2.0,
+ "Volume": "40",
+ "liquidtype": "Tip Contents",
+ "WellsX": 12,
+ "LabwareClass": "Matrix96_750uL",
+ "AutoSelectPrototype": true,
+ "ColsFirst": true,
+ "CustomHeight": false,
+ "DataSetPattern": false,
+ "HeightFrom": 0,
+ "LocalPattern": true,
+ "Operation": "Dispense",
+ "OverrideHeight": false,
+ "Pattern": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "Prototype": "MC P300 High",
+ "ReferencedPattern": "",
+ "RowsFirst": false,
+ "SectionExpression": "",
+ "SelectionInfo": [
+ 1
+ ],
+ "SetMark": true,
+ "Source": false,
+ "StartAtMark": false,
+ "StartAtSelection": true,
+ "UseExpression": false
+ }
+ ],
+ "Wash": false,
+ "Dynamic?": true,
+ "AutoSelectActiveWashTechnique": false,
+ "ActiveWashTechnique": "",
+ "ChangeTipsBetweenDests": true,
+ "ChangeTipsBetweenSources": false,
+ "DefaultCaption": "",
+ "UseExpression": false,
+ "LeaveTipsOn": false,
+ "MandrelExpression": "",
+ "Repeats": "1",
+ "RepeatsByVolume": false,
+ "Replicates": "1",
+ "ShowTipHandlingDetails": false,
+ "ShowTransferDetails": true,
+ "Solvent": "Water",
+ "Span8Wash": false,
+ "Span8WashVolume": "2",
+ "Span8WasteVolume": "1",
+ "SplitVolume": false,
+ "SplitVolumeCleaning": false,
+ "Stop": "Destinations",
+ "TipLocation": "BC230",
+ "UseCurrentTips": false,
+ "UseDisposableTips": false,
+ "UseFixedTips": false,
+ "UseJIT": true,
+ "UseMandrelSelection": true,
+ "UseProbes": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "WashCycles": "4",
+ "WashVolume": "110%",
+ "Wizard": false
+ }
+ },
+ {
+ "transfer": {
+ "Span8": false,
+ "Pod": "Pod1",
+ "items": [
+ {
+ "Position": "P12",
+ "Height": -2.0,
+ "Volume": "40",
+ "liquidtype": "Well Contents",
+ "WellsX": 12,
+ "LabwareClass": "Matrix96_750uL",
+ "AutoSelectPrototype": true,
+ "ColsFirst": true,
+ "CustomHeight": false,
+ "DataSetPattern": false,
+ "HeightFrom": 0,
+ "LocalPattern": true,
+ "Operation": "Aspirate",
+ "OverrideHeight": false,
+ "Pattern": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "Prototype": "MC P300 High",
+ "ReferencedPattern": "",
+ "RowsFirst": false,
+ "SectionExpression": "",
+ "SelectionInfo": [
+ 1
+ ],
+ "SetMark": true,
+ "Source": true,
+ "StartAtMark": false,
+ "StartAtSelection": true,
+ "UseExpression": false
+ },
+ {
+ "Position": "P13",
+ "Height": -2.0,
+ "Volume": "40",
+ "liquidtype": "Tip Contents",
+ "WellsX": 12,
+ "LabwareClass": "Matrix96_750uL",
+ "AutoSelectPrototype": true,
+ "ColsFirst": true,
+ "CustomHeight": false,
+ "DataSetPattern": false,
+ "HeightFrom": 0,
+ "LocalPattern": true,
+ "Operation": "Dispense",
+ "OverrideHeight": false,
+ "Pattern": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "Prototype": "MC P300 High",
+ "ReferencedPattern": "",
+ "RowsFirst": false,
+ "SectionExpression": "",
+ "SelectionInfo": [
+ 1
+ ],
+ "SetMark": true,
+ "Source": false,
+ "StartAtMark": false,
+ "StartAtSelection": true,
+ "UseExpression": false
+ }
+ ],
+ "Wash": false,
+ "Dynamic?": true,
+ "AutoSelectActiveWashTechnique": false,
+ "ActiveWashTechnique": "",
+ "ChangeTipsBetweenDests": true,
+ "ChangeTipsBetweenSources": false,
+ "DefaultCaption": "",
+ "UseExpression": false,
+ "LeaveTipsOn": false,
+ "MandrelExpression": "",
+ "Repeats": "1",
+ "RepeatsByVolume": false,
+ "Replicates": "1",
+ "ShowTipHandlingDetails": false,
+ "ShowTransferDetails": true,
+ "Solvent": "Water",
+ "Span8Wash": false,
+ "Span8WashVolume": "2",
+ "Span8WasteVolume": "1",
+ "SplitVolume": false,
+ "SplitVolumeCleaning": false,
+ "Stop": "Destinations",
+ "TipLocation": "BC230",
+ "UseCurrentTips": false,
+ "UseDisposableTips": false,
+ "UseFixedTips": false,
+ "UseJIT": true,
+ "UseMandrelSelection": true,
+ "UseProbes": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "WashCycles": "4",
+ "WashVolume": "110%",
+ "Wizard": false
+ }
+ },
+ {
+ "move": {
+ "Pod": "Pod1",
+ "GripSide": "A1 near",
+ "Source": "P12",
+ "Target": "Orbital1",
+ "LeaveBottomLabware": false
+ }
+ },
+ {
+ "oscillation": {
+ "Device": "OrbitalShaker0",
+ "Parameters": [
+ "800",
+ "2",
+ "45",
+ "CounterClockwise"
+ ],
+ "Command": "Timed Shake"
+ }
+ },
+ {
+ "move": {
+ "Pod": "Pod1",
+ "GripSide": "A1 near",
+ "Source": "Orbital1",
+ "Target": "P12",
+ "LeaveBottomLabware": false
+ }
+ },
+ {
+ "incubation": {
+ "Message": "Paused",
+ "Location": "the whole system",
+ "Time": 180,
+ "Mode": "TimedResource"
+ }
+ },
+ {
+ "transfer": {
+ "Span8": false,
+ "Pod": "Pod1",
+ "items": [
+ {
+ "Position": "P12",
+ "Height": -2.0,
+ "Volume": "40",
+ "liquidtype": "Well Contents",
+ "WellsX": 12,
+ "LabwareClass": "Matrix96_750uL",
+ "AutoSelectPrototype": true,
+ "ColsFirst": true,
+ "CustomHeight": false,
+ "DataSetPattern": false,
+ "HeightFrom": 0,
+ "LocalPattern": true,
+ "Operation": "Aspirate",
+ "OverrideHeight": false,
+ "Pattern": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "Prototype": "MC P300 High",
+ "ReferencedPattern": "",
+ "RowsFirst": false,
+ "SectionExpression": "",
+ "SelectionInfo": [
+ 1
+ ],
+ "SetMark": true,
+ "Source": true,
+ "StartAtMark": false,
+ "StartAtSelection": true,
+ "UseExpression": false
+ },
+ {
+ "Position": "P13",
+ "Height": -2.0,
+ "Volume": "40",
+ "liquidtype": "Tip Contents",
+ "WellsX": 12,
+ "LabwareClass": "Matrix96_750uL",
+ "AutoSelectPrototype": true,
+ "ColsFirst": true,
+ "CustomHeight": false,
+ "DataSetPattern": false,
+ "HeightFrom": 0,
+ "LocalPattern": true,
+ "Operation": "Dispense",
+ "OverrideHeight": false,
+ "Pattern": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "Prototype": "MC P300 High",
+ "ReferencedPattern": "",
+ "RowsFirst": false,
+ "SectionExpression": "",
+ "SelectionInfo": [
+ 1
+ ],
+ "SetMark": true,
+ "Source": false,
+ "StartAtMark": false,
+ "StartAtSelection": true,
+ "UseExpression": false
+ }
+ ],
+ "Wash": false,
+ "Dynamic?": true,
+ "AutoSelectActiveWashTechnique": false,
+ "ActiveWashTechnique": "",
+ "ChangeTipsBetweenDests": true,
+ "ChangeTipsBetweenSources": false,
+ "DefaultCaption": "",
+ "UseExpression": false,
+ "LeaveTipsOn": false,
+ "MandrelExpression": "",
+ "Repeats": "1",
+ "RepeatsByVolume": false,
+ "Replicates": "1",
+ "ShowTipHandlingDetails": false,
+ "ShowTransferDetails": true,
+ "Solvent": "Water",
+ "Span8Wash": false,
+ "Span8WashVolume": "2",
+ "Span8WasteVolume": "1",
+ "SplitVolume": false,
+ "SplitVolumeCleaning": false,
+ "Stop": "Destinations",
+ "TipLocation": "BC230",
+ "UseCurrentTips": false,
+ "UseDisposableTips": false,
+ "UseFixedTips": false,
+ "UseJIT": true,
+ "UseMandrelSelection": true,
+ "UseProbes": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "WashCycles": "4",
+ "WashVolume": "110%",
+ "Wizard": false
+ }
+ },
+ {
+ "transfer": {
+ "Span8": false,
+ "Pod": "Pod1",
+ "items": [
+ {
+ "Position": "P12",
+ "Height": -2.0,
+ "Volume": "40",
+ "liquidtype": "Well Contents",
+ "WellsX": 12,
+ "LabwareClass": "Matrix96_750uL",
+ "AutoSelectPrototype": true,
+ "ColsFirst": true,
+ "CustomHeight": false,
+ "DataSetPattern": false,
+ "HeightFrom": 0,
+ "LocalPattern": true,
+ "Operation": "Aspirate",
+ "OverrideHeight": false,
+ "Pattern": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "Prototype": "MC P300 High",
+ "ReferencedPattern": "",
+ "RowsFirst": false,
+ "SectionExpression": "",
+ "SelectionInfo": [
+ 1
+ ],
+ "SetMark": true,
+ "Source": true,
+ "StartAtMark": false,
+ "StartAtSelection": true,
+ "UseExpression": false
+ },
+ {
+ "Position": "P13",
+ "Height": -2.0,
+ "Volume": "40",
+ "liquidtype": "Tip Contents",
+ "WellsX": 12,
+ "LabwareClass": "Matrix96_750uL",
+ "AutoSelectPrototype": true,
+ "ColsFirst": true,
+ "CustomHeight": false,
+ "DataSetPattern": false,
+ "HeightFrom": 0,
+ "LocalPattern": true,
+ "Operation": "Dispense",
+ "OverrideHeight": false,
+ "Pattern": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "Prototype": "MC P300 High",
+ "ReferencedPattern": "",
+ "RowsFirst": false,
+ "SectionExpression": "",
+ "SelectionInfo": [
+ 1
+ ],
+ "SetMark": true,
+ "Source": false,
+ "StartAtMark": false,
+ "StartAtSelection": true,
+ "UseExpression": false
+ }
+ ],
+ "Wash": false,
+ "Dynamic?": true,
+ "AutoSelectActiveWashTechnique": false,
+ "ActiveWashTechnique": "",
+ "ChangeTipsBetweenDests": true,
+ "ChangeTipsBetweenSources": false,
+ "DefaultCaption": "",
+ "UseExpression": false,
+ "LeaveTipsOn": false,
+ "MandrelExpression": "",
+ "Repeats": "1",
+ "RepeatsByVolume": false,
+ "Replicates": "1",
+ "ShowTipHandlingDetails": false,
+ "ShowTransferDetails": true,
+ "Solvent": "Water",
+ "Span8Wash": false,
+ "Span8WashVolume": "2",
+ "Span8WasteVolume": "1",
+ "SplitVolume": false,
+ "SplitVolumeCleaning": false,
+ "Stop": "Destinations",
+ "TipLocation": "BC230",
+ "UseCurrentTips": false,
+ "UseDisposableTips": false,
+ "UseFixedTips": false,
+ "UseJIT": true,
+ "UseMandrelSelection": true,
+ "UseProbes": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "WashCycles": "4",
+ "WashVolume": "110%",
+ "Wizard": false
+ }
+ },
+ {
+ "move": {
+ "Pod": "Pod1",
+ "GripSide": "A1 near",
+ "Source": "P12",
+ "Target": "Orbital1",
+ "LeaveBottomLabware": false
+ }
+ },
+ {
+ "oscillation": {
+ "Device": "OrbitalShaker0",
+ "Parameters": [
+ "800",
+ "2",
+ "45",
+ "CounterClockwise"
+ ],
+ "Command": "Timed Shake"
+ }
+ },
+ {
+ "move": {
+ "Pod": "Pod1",
+ "GripSide": "A1 near",
+ "Source": "Orbital1",
+ "Target": "P12",
+ "LeaveBottomLabware": false
+ }
+ },
+ {
+ "incubation": {
+ "Message": "Paused",
+ "Location": "the whole system",
+ "Time": 180,
+ "Mode": "TimedResource"
+ }
+ },
+ {
+ "transfer": {
+ "Span8": false,
+ "Pod": "Pod1",
+ "items": [
+ {
+ "Position": "P12",
+ "Height": -2.0,
+ "Volume": "40",
+ "liquidtype": "Well Contents",
+ "WellsX": 12,
+ "LabwareClass": "Matrix96_750uL",
+ "AutoSelectPrototype": true,
+ "ColsFirst": true,
+ "CustomHeight": false,
+ "DataSetPattern": false,
+ "HeightFrom": 0,
+ "LocalPattern": true,
+ "Operation": "Aspirate",
+ "OverrideHeight": false,
+ "Pattern": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "Prototype": "MC P300 High",
+ "ReferencedPattern": "",
+ "RowsFirst": false,
+ "SectionExpression": "",
+ "SelectionInfo": [
+ 1
+ ],
+ "SetMark": true,
+ "Source": true,
+ "StartAtMark": false,
+ "StartAtSelection": true,
+ "UseExpression": false
+ },
+ {
+ "Position": "P13",
+ "Height": -2.0,
+ "Volume": "40",
+ "liquidtype": "Tip Contents",
+ "WellsX": 12,
+ "LabwareClass": "Matrix96_750uL",
+ "AutoSelectPrototype": true,
+ "ColsFirst": true,
+ "CustomHeight": false,
+ "DataSetPattern": false,
+ "HeightFrom": 0,
+ "LocalPattern": true,
+ "Operation": "Dispense",
+ "OverrideHeight": false,
+ "Pattern": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "Prototype": "MC P300 High",
+ "ReferencedPattern": "",
+ "RowsFirst": false,
+ "SectionExpression": "",
+ "SelectionInfo": [
+ 1
+ ],
+ "SetMark": true,
+ "Source": false,
+ "StartAtMark": false,
+ "StartAtSelection": true,
+ "UseExpression": false
+ }
+ ],
+ "Wash": false,
+ "Dynamic?": true,
+ "AutoSelectActiveWashTechnique": false,
+ "ActiveWashTechnique": "",
+ "ChangeTipsBetweenDests": true,
+ "ChangeTipsBetweenSources": false,
+ "DefaultCaption": "",
+ "UseExpression": false,
+ "LeaveTipsOn": false,
+ "MandrelExpression": "",
+ "Repeats": "1",
+ "RepeatsByVolume": false,
+ "Replicates": "1",
+ "ShowTipHandlingDetails": false,
+ "ShowTransferDetails": true,
+ "Solvent": "Water",
+ "Span8Wash": false,
+ "Span8WashVolume": "2",
+ "Span8WasteVolume": "1",
+ "SplitVolume": false,
+ "SplitVolumeCleaning": false,
+ "Stop": "Destinations",
+ "TipLocation": "BC230",
+ "UseCurrentTips": false,
+ "UseDisposableTips": false,
+ "UseFixedTips": false,
+ "UseJIT": true,
+ "UseMandrelSelection": true,
+ "UseProbes": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "WashCycles": "4",
+ "WashVolume": "110%",
+ "Wizard": false
+ }
+ },
+ {
+ "incubation": {
+ "Message": "Paused",
+ "Location": "the whole system",
+ "Time": 900,
+ "Mode": "TimedResource"
+ }
+ },
+ {
+ "transfer": {
+ "Span8": false,
+ "Pod": "Pod1",
+ "items": [
+ {
+ "Position": "P12",
+ "Height": -2.0,
+ "Volume": "40",
+ "liquidtype": "Well Contents",
+ "WellsX": 12,
+ "LabwareClass": "Matrix96_750uL",
+ "AutoSelectPrototype": true,
+ "ColsFirst": true,
+ "CustomHeight": false,
+ "DataSetPattern": false,
+ "HeightFrom": 0,
+ "LocalPattern": true,
+ "Operation": "Aspirate",
+ "OverrideHeight": false,
+ "Pattern": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "Prototype": "MC P300 High",
+ "ReferencedPattern": "",
+ "RowsFirst": false,
+ "SectionExpression": "",
+ "SelectionInfo": [
+ 1
+ ],
+ "SetMark": true,
+ "Source": true,
+ "StartAtMark": false,
+ "StartAtSelection": true,
+ "UseExpression": false
+ },
+ {
+ "Position": "P13",
+ "Height": -2.0,
+ "Volume": "40",
+ "liquidtype": "Tip Contents",
+ "WellsX": 12,
+ "LabwareClass": "Matrix96_750uL",
+ "AutoSelectPrototype": true,
+ "ColsFirst": true,
+ "CustomHeight": false,
+ "DataSetPattern": false,
+ "HeightFrom": 0,
+ "LocalPattern": true,
+ "Operation": "Dispense",
+ "OverrideHeight": false,
+ "Pattern": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "Prototype": "MC P300 High",
+ "ReferencedPattern": "",
+ "RowsFirst": false,
+ "SectionExpression": "",
+ "SelectionInfo": [
+ 1
+ ],
+ "SetMark": true,
+ "Source": false,
+ "StartAtMark": false,
+ "StartAtSelection": true,
+ "UseExpression": false
+ }
+ ],
+ "Wash": false,
+ "Dynamic?": true,
+ "AutoSelectActiveWashTechnique": false,
+ "ActiveWashTechnique": "",
+ "ChangeTipsBetweenDests": true,
+ "ChangeTipsBetweenSources": false,
+ "DefaultCaption": "",
+ "UseExpression": false,
+ "LeaveTipsOn": false,
+ "MandrelExpression": "",
+ "Repeats": "1",
+ "RepeatsByVolume": false,
+ "Replicates": "1",
+ "ShowTipHandlingDetails": false,
+ "ShowTransferDetails": true,
+ "Solvent": "Water",
+ "Span8Wash": false,
+ "Span8WashVolume": "2",
+ "Span8WasteVolume": "1",
+ "SplitVolume": false,
+ "SplitVolumeCleaning": false,
+ "Stop": "Destinations",
+ "TipLocation": "BC230",
+ "UseCurrentTips": false,
+ "UseDisposableTips": false,
+ "UseFixedTips": false,
+ "UseJIT": true,
+ "UseMandrelSelection": true,
+ "UseProbes": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "WashCycles": "4",
+ "WashVolume": "110%",
+ "Wizard": false
+ }
+ },
+ {
+ "move": {
+ "Pod": "Pod1",
+ "GripSide": "A1 near",
+ "Source": "P12",
+ "Target": "Orbital1",
+ "LeaveBottomLabware": false
+ }
+ },
+ {
+ "oscillation": {
+ "Device": "OrbitalShaker0",
+ "Parameters": [
+ "800",
+ "2",
+ "60",
+ "CounterClockwise"
+ ],
+ "Command": "Timed Shake"
+ }
+ },
+ {
+ "move": {
+ "Pod": "Pod1",
+ "GripSide": "A1 near",
+ "Source": "Orbital1",
+ "Target": "P12",
+ "LeaveBottomLabware": false
+ }
+ },
+ {
+ "incubation": {
+ "Message": "Paused",
+ "Location": "the whole system",
+ "Time": 180,
+ "Mode": "TimedResource"
+ }
+ },
+ {
+ "transfer": {
+ "Span8": false,
+ "Pod": "Pod1",
+ "items": [
+ {
+ "Position": "P12",
+ "Height": -2.0,
+ "Volume": "40",
+ "liquidtype": "Well Contents",
+ "WellsX": 12,
+ "LabwareClass": "Matrix96_750uL",
+ "AutoSelectPrototype": true,
+ "ColsFirst": true,
+ "CustomHeight": false,
+ "DataSetPattern": false,
+ "HeightFrom": 0,
+ "LocalPattern": true,
+ "Operation": "Aspirate",
+ "OverrideHeight": false,
+ "Pattern": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "Prototype": "MC P300 High",
+ "ReferencedPattern": "",
+ "RowsFirst": false,
+ "SectionExpression": "",
+ "SelectionInfo": [
+ 1
+ ],
+ "SetMark": true,
+ "Source": true,
+ "StartAtMark": false,
+ "StartAtSelection": true,
+ "UseExpression": false
+ },
+ {
+ "Position": "P13",
+ "Height": -2.0,
+ "Volume": "40",
+ "liquidtype": "Tip Contents",
+ "WellsX": 12,
+ "LabwareClass": "Matrix96_750uL",
+ "AutoSelectPrototype": true,
+ "ColsFirst": true,
+ "CustomHeight": false,
+ "DataSetPattern": false,
+ "HeightFrom": 0,
+ "LocalPattern": true,
+ "Operation": "Dispense",
+ "OverrideHeight": false,
+ "Pattern": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "Prototype": "MC P300 High",
+ "ReferencedPattern": "",
+ "RowsFirst": false,
+ "SectionExpression": "",
+ "SelectionInfo": [
+ 1
+ ],
+ "SetMark": true,
+ "Source": false,
+ "StartAtMark": false,
+ "StartAtSelection": true,
+ "UseExpression": false
+ }
+ ],
+ "Wash": false,
+ "Dynamic?": true,
+ "AutoSelectActiveWashTechnique": false,
+ "ActiveWashTechnique": "",
+ "ChangeTipsBetweenDests": true,
+ "ChangeTipsBetweenSources": false,
+ "DefaultCaption": "",
+ "UseExpression": false,
+ "LeaveTipsOn": false,
+ "MandrelExpression": "",
+ "Repeats": "1",
+ "RepeatsByVolume": false,
+ "Replicates": "1",
+ "ShowTipHandlingDetails": false,
+ "ShowTransferDetails": true,
+ "Solvent": "Water",
+ "Span8Wash": false,
+ "Span8WashVolume": "2",
+ "Span8WasteVolume": "1",
+ "SplitVolume": false,
+ "SplitVolumeCleaning": false,
+ "Stop": "Destinations",
+ "TipLocation": "BC230",
+ "UseCurrentTips": false,
+ "UseDisposableTips": false,
+ "UseFixedTips": false,
+ "UseJIT": true,
+ "UseMandrelSelection": true,
+ "UseProbes": [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true
+ ],
+ "WashCycles": "4",
+ "WashVolume": "110%",
+ "Wizard": false
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/unilabos/devices/liquid_handling/complete_biomek_protocol_0608.json b/unilabos/devices/liquid_handling/complete_biomek_protocol_0608.json
index 1feaaa4..24b3d45 100644
--- a/unilabos/devices/liquid_handling/complete_biomek_protocol_0608.json
+++ b/unilabos/devices/liquid_handling/complete_biomek_protocol_0608.json
@@ -643,6 +643,222 @@
]
}
],
+ "P12": [
+ {
+ "Properties": {
+ "Name": "working plate on P12",
+ "Device": "",
+ "liquidtype": "Water",
+ "BarCode": "",
+ "SenseEveryTime": false
+ },
+ "Known": true,
+ "Class": "LabwareClasses\\BCDeep96Round",
+ "DataSets": {
+ "Volume": {}
+ },
+ "RuntimeDataSets": {
+ "Volume": {}
+ },
+ "EvalAmounts": [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "Nominal": false,
+ "EvalLiquids": [
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water",
+ "Water"
+ ]
+ }
+ ],
"P13": [
{
"Properties": {
@@ -1110,9 +1326,9 @@
"Pod": "Pod1",
"items": [
{
- "Position": "P1",
+ "Position": "P12",
"Height": -2.0,
- "Volume": "50",
+ "Volume": "40",
"liquidtype": "Well Contents",
"WellsX": 12,
"LabwareClass": "Matrix96_750uL",
@@ -1219,7 +1435,6 @@
true,
true,
true,
- true,
true
],
"Prototype": "MC P300 High",
@@ -1236,9 +1451,9 @@
"UseExpression": false
},
{
- "Position": "P11",
+ "Position": "P14",
"Height": -2.0,
- "Volume": "50",
+ "Volume": "40",
"liquidtype": "Tip Contents",
"WellsX": 12,
"LabwareClass": "Matrix96_750uL",
@@ -1411,9 +1626,9 @@
"Pod": "Pod1",
"items": [
{
- "Position": "P2",
+ "Position": "P12",
"Height": -2.0,
- "Volume": "100",
+ "Volume": "40",
"liquidtype": "Well Contents",
"WellsX": 12,
"LabwareClass": "Matrix96_750uL",
@@ -1520,7 +1735,6 @@
true,
true,
true,
- true,
true
],
"Prototype": "MC P300 High",
@@ -1537,9 +1751,9 @@
"UseExpression": false
},
{
- "Position": "P11",
+ "Position": "P14",
"Height": -2.0,
- "Volume": "100",
+ "Volume": "40",
"liquidtype": "Tip Contents",
"WellsX": 12,
"LabwareClass": "Matrix96_750uL",
@@ -1743,7 +1957,7 @@
{
"Position": "P12",
"Height": -2.0,
- "Volume": "150",
+ "Volume": "40",
"liquidtype": "Well Contents",
"WellsX": 12,
"LabwareClass": "Matrix96_750uL",
@@ -1850,7 +2064,6 @@
true,
true,
true,
- true,
true
],
"Prototype": "MC P300 High",
@@ -1867,9 +2080,9 @@
"UseExpression": false
},
{
- "Position": "P22",
+ "Position": "P14",
"Height": -2.0,
- "Volume": "150",
+ "Volume": "40",
"liquidtype": "Tip Contents",
"WellsX": 12,
"LabwareClass": "Matrix96_750uL",
@@ -2042,9 +2255,9 @@
"Pod": "Pod1",
"items": [
{
- "Position": "P3",
+ "Position": "P12",
"Height": -2.0,
- "Volume": "400",
+ "Volume": "40",
"liquidtype": "Well Contents",
"WellsX": 12,
"LabwareClass": "Matrix96_750uL",
@@ -2151,7 +2364,6 @@
true,
true,
true,
- true,
true
],
"Prototype": "MC P300 High",
@@ -2168,9 +2380,9 @@
"UseExpression": false
},
{
- "Position": "P12",
+ "Position": "P14",
"Height": -2.0,
- "Volume": "400",
+ "Volume": "40",
"liquidtype": "Tip Contents",
"WellsX": 12,
"LabwareClass": "Matrix96_750uL",
@@ -2383,7 +2595,7 @@
{
"Position": "P12",
"Height": -2.0,
- "Volume": "400",
+ "Volume": "40",
"liquidtype": "Well Contents",
"WellsX": 12,
"LabwareClass": "Matrix96_750uL",
@@ -2490,7 +2702,6 @@
true,
true,
true,
- true,
true
],
"Prototype": "MC P300 High",
@@ -2507,9 +2718,9 @@
"UseExpression": false
},
{
- "Position": "P22",
+ "Position": "P14",
"Height": -2.0,
- "Volume": "400",
+ "Volume": "40",
"liquidtype": "Tip Contents",
"WellsX": 12,
"LabwareClass": "Matrix96_750uL",
@@ -2682,9 +2893,9 @@
"Pod": "Pod1",
"items": [
{
- "Position": "P3",
+ "Position": "P12",
"Height": -2.0,
- "Volume": "400",
+ "Volume": "40",
"liquidtype": "Well Contents",
"WellsX": 12,
"LabwareClass": "Matrix96_750uL",
@@ -2791,7 +3002,6 @@
true,
true,
true,
- true,
true
],
"Prototype": "MC P300 High",
@@ -2808,9 +3018,9 @@
"UseExpression": false
},
{
- "Position": "P12",
+ "Position": "P14",
"Height": -2.0,
- "Volume": "400",
+ "Volume": "40",
"liquidtype": "Tip Contents",
"WellsX": 12,
"LabwareClass": "Matrix96_750uL",
@@ -3023,7 +3233,7 @@
{
"Position": "P12",
"Height": -2.0,
- "Volume": "400",
+ "Volume": "40",
"liquidtype": "Well Contents",
"WellsX": 12,
"LabwareClass": "Matrix96_750uL",
@@ -3130,7 +3340,6 @@
true,
true,
true,
- true,
true
],
"Prototype": "MC P300 High",
@@ -3147,9 +3356,9 @@
"UseExpression": false
},
{
- "Position": "P22",
+ "Position": "P14",
"Height": -2.0,
- "Volume": "400",
+ "Volume": "40",
"liquidtype": "Tip Contents",
"WellsX": 12,
"LabwareClass": "Matrix96_750uL",
@@ -3339,7 +3548,7 @@
"Pod": "Pod1",
"items": [
{
- "Position": "P4",
+ "Position": "P12",
"Height": -2.0,
"Volume": "40",
"liquidtype": "Well Contents",
@@ -3448,7 +3657,6 @@
true,
true,
true,
- true,
true
],
"Prototype": "MC P300 High",
@@ -3465,7 +3673,7 @@
"UseExpression": false
},
{
- "Position": "P13",
+ "Position": "P14",
"Height": -2.0,
"Volume": "40",
"liquidtype": "Tip Contents",
@@ -3804,7 +4012,6 @@
true,
true,
true,
- true,
true
],
"Prototype": "MC P300 High",
diff --git a/unilabos/devices/liquid_handling/converted protocol/sci-lucif-assay4_plr_background_tested.ipynb b/unilabos/devices/liquid_handling/converted protocol/sci-lucif-assay4_plr_background_tested.ipynb
index daf47e2..f380fc6 100644
--- a/unilabos/devices/liquid_handling/converted protocol/sci-lucif-assay4_plr_background_tested.ipynb
+++ b/unilabos/devices/liquid_handling/converted protocol/sci-lucif-assay4_plr_background_tested.ipynb
@@ -2,18 +2,18 @@
"cells": [
{
"cell_type": "code",
- "execution_count": 9,
"id": "6e581f88",
- "metadata": {},
- "outputs": [],
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2025-06-08T15:32:44.429407Z",
+ "start_time": "2025-06-08T15:32:43.584559Z"
+ }
+ },
"source": [
"# NF‑κB Luciferase Reporter Assay – pylabrobot version\n",
"\n",
"import os\n",
"import sys\n",
- "os.getcwd()\n",
- "sys.path.append('/Users/guangxinzhang/Documents/Deep Potential/pylabrobot/myfile')\n",
- "\n",
"from pylabrobot.resources import Coordinate\n",
"from pylabrobot.liquid_handling.backends.chatterbox import LiquidHandlerChatterboxBackend\n",
"from pylabrobot.visualizer.visualizer import Visualizer\n",
@@ -24,33 +24,26 @@
" nest_1_reservoir_195ml,\n",
" opentrons_96_tiprack_300ul\n",
")\n",
- "from High_level_function.action_definition import DPLiquidHandler"
- ]
+ "from pylabrobot.liquid_handling import LiquidHandler"
+ ],
+ "outputs": [],
+ "execution_count": 1
},
{
"cell_type": "code",
- "execution_count": 10,
"id": "c3127d6e",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Setting up the liquid handler.\n",
- "Resource deck was assigned to the liquid handler.\n",
- "Resource trash_container was assigned to the liquid handler.\n",
- "Resource tiprack_1 was assigned to the liquid handler.\n",
- "Resource tiprack_4 was assigned to the liquid handler.\n",
- "Resource tiprack_8 was assigned to the liquid handler.\n",
- "Resource tiprack_11 was assigned to the liquid handler.\n",
- "Resource working_plate was assigned to the liquid handler.\n",
- "Resource reagent_stock was assigned to the liquid handler.\n",
- "Resource waste_liq was assigned to the liquid handler.\n"
- ]
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2025-06-08T15:32:45.234924Z",
+ "start_time": "2025-06-08T15:32:45.194957Z"
}
- ],
+ },
"source": [
+ "\n",
+ "# from pylabrobot.resources import set_volume_tracking\n",
+ "# from pylabrobot.resources import set_tip_tracking\n",
+ "# set_volume_tracking(enabled=True)\n",
+ "# set_tip_tracking(enabled=True)\n",
"# ──────────────────────────────────────\n",
"# User‑configurable constants (µL)\n",
"MEDIUM_VOL = 100 # volume of spent medium to remove\n",
@@ -62,7 +55,7 @@
"\n",
"# ──────────────────────────────────────\n",
"\n",
- "lh = DPLiquidHandler(backend=LiquidHandlerChatterboxBackend(), deck=OTDeck())\n",
+ "lh = LiquidHandler(backend=LiquidHandlerChatterboxBackend(), deck=OTDeck())\n",
"await lh.setup()\n",
"#vis = Visualizer(resource=lh)\n",
"#await vis.setup()\n",
@@ -88,14 +81,36 @@
"# 1‑channel waste reservoir at slot 9\n",
"waste_liq = nest_1_reservoir_195ml(name='waste_liq')\n",
"lh.deck.assign_child_at_slot(waste_liq, slot=9)"
- ]
+ ],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Setting up the liquid handler.\n",
+ "Resource deck was assigned to the liquid handler.\n",
+ "Resource trash_container was assigned to the liquid handler.\n",
+ "Resource tiprack_1 was assigned to the liquid handler.\n",
+ "Resource tiprack_4 was assigned to the liquid handler.\n",
+ "Resource tiprack_8 was assigned to the liquid handler.\n",
+ "Resource tiprack_11 was assigned to the liquid handler.\n",
+ "Resource working_plate was assigned to the liquid handler.\n",
+ "Resource reagent_stock was assigned to the liquid handler.\n",
+ "Resource waste_liq was assigned to the liquid handler.\n"
+ ]
+ }
+ ],
+ "execution_count": 2
},
{
"cell_type": "code",
- "execution_count": 11,
"id": "b5313453",
- "metadata": {},
- "outputs": [],
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2025-06-08T15:32:45.425953Z",
+ "start_time": "2025-06-08T15:32:45.420965Z"
+ }
+ },
"source": [
"pbs = reagent_stock[0][0]\n",
"lysis = reagent_stock[1][0]\n",
@@ -103,14 +118,19 @@
"waste_liq = waste_liq[0]\n",
"wells_name = [f\"A{i}\" for i in range(1, 13)]\n",
"cells_all = working_plate[wells_name] # A1–A12"
- ]
+ ],
+ "outputs": [],
+ "execution_count": 3
},
{
"cell_type": "code",
- "execution_count": 12,
"id": "e85d6752",
- "metadata": {},
- "outputs": [],
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2025-06-08T15:32:46.480024Z",
+ "start_time": "2025-06-08T15:32:46.473896Z"
+ }
+ },
"source": [
"working_plate_volumes = [\n",
" ('culture medium', MEDIUM_VOL) if i % 8 == 0 else (None, 0)\n",
@@ -119,14 +139,54 @@
"working_plate.set_well_liquids(working_plate_volumes)\n",
"reagent_info = [('PBS Buffer', 5000), ('Lysis Buffer', 5000), ('Luciferase Reagent', 5000)]+[ (None, 0) ]* 9\n",
"reagent_stock.set_well_liquids(reagent_info)\n",
- "lh.set_tiprack(list(tipracks.values()))"
- ]
+ "# lh.deck.set_tiprack(list(tipracks.values()))"
+ ],
+ "outputs": [],
+ "execution_count": 4
+ },
+ {
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2025-06-08T15:32:47.742983Z",
+ "start_time": "2025-06-08T15:32:47.731878Z"
+ }
+ },
+ "cell_type": "code",
+ "source": [
+ "# state = reagent_stock.serialize_all_state()\n",
+ "# print(state)\n",
+ "reagent_stock.load_all_state({'reagent_stock': {}, 'reagent_stock_A1': {'liquids': [['PBS Buffer', 5000]], 'pending_liquids': [], 'liquid_history': []}, 'reagent_stock_A2': {'liquids': [['Lysis Buffer', 5000]], 'pending_liquids': [['Lysis Buffer', 5000]], 'liquid_history': ['Lysis Buffer']}, 'reagent_stock_A3': {'liquids': [['Luciferase Reagent', 5000]], 'pending_liquids': [['Luciferase Reagent', 5000]], 'liquid_history': ['Luciferase Reagent']}, 'reagent_stock_A4': {'liquids': [[None, 0]], 'pending_liquids': [[None, 0]], 'liquid_history': [None]}, 'reagent_stock_A5': {'liquids': [[None, 0]], 'pending_liquids': [[None, 0]], 'liquid_history': [None]}, 'reagent_stock_A6': {'liquids': [[None, 0]], 'pending_liquids': [[None, 0]], 'liquid_history': [None]}, 'reagent_stock_A7': {'liquids': [[None, 0]], 'pending_liquids': [[None, 0]], 'liquid_history': [None]}, 'reagent_stock_A8': {'liquids': [[None, 0]], 'pending_liquids': [[None, 0]], 'liquid_history': [None]}, 'reagent_stock_A9': {'liquids': [[None, 0]], 'pending_liquids': [[None, 0]], 'liquid_history': [None]}, 'reagent_stock_A10': {'liquids': [[None, 0]], 'pending_liquids': [[None, 0]], 'liquid_history': [None]}, 'reagent_stock_A11': {'liquids': [[None, 0]], 'pending_liquids': [[None, 0]], 'liquid_history': [None]}, 'reagent_stock_A12': {'liquids': [[None, 0]], 'pending_liquids': [[None, 0]], 'liquid_history': [None]}})\n",
+ "\n",
+ "reagent_stock[0][0].tracker.liquids"
+ ],
+ "id": "cd6ad8fb6494f14a",
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[('PBS Buffer', 5000)]"
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "execution_count": 5
},
{
"cell_type": "code",
- "execution_count": 13,
"id": "9dbfb0e2",
- "metadata": {},
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2025-06-08T15:32:02.047523Z",
+ "start_time": "2025-06-08T15:32:02.042034Z"
+ }
+ },
+ "source": [
+ "from pylabrobot.resources import set_tip_tracking, set_volume_tracking\n",
+ "set_tip_tracking(True), set_volume_tracking(True)"
+ ],
"outputs": [
{
"data": {
@@ -134,185 +194,9106 @@
"(None, None)"
]
},
- "execution_count": 13,
+ "execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
- "source": [
- "from pylabrobot.resources import set_tip_tracking, set_volume_tracking\n",
- "set_tip_tracking(True), set_volume_tracking(True)"
- ]
+ "execution_count": 12
+ },
+ {
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2025-06-08T16:04:23.597819Z",
+ "start_time": "2025-06-08T16:04:23.427478Z"
+ }
+ },
+ "cell_type": "code",
+ "source": "lh.serialize()",
+ "id": "6b2801f34ac96ef6",
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'name': 'lh_deck',\n",
+ " 'type': 'LiquidHandler',\n",
+ " 'size_x': 624.3,\n",
+ " 'size_y': 565.2,\n",
+ " 'size_z': 900,\n",
+ " 'location': {'x': 0, 'y': 0, 'z': 0, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'liquid_handler',\n",
+ " 'model': None,\n",
+ " 'children': [{'name': 'deck',\n",
+ " 'type': 'OTDeck',\n",
+ " 'size_x': 624.3,\n",
+ " 'size_y': 565.2,\n",
+ " 'size_z': 900,\n",
+ " 'location': {'x': 0, 'y': 0, 'z': 0, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'deck',\n",
+ " 'children': [{'name': 'trash_container',\n",
+ " 'type': 'Resource',\n",
+ " 'size_x': 172.86,\n",
+ " 'size_y': 165.86,\n",
+ " 'size_z': 82,\n",
+ " 'location': {'x': 265.0, 'y': 271.5, 'z': 0.0, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': None,\n",
+ " 'model': None,\n",
+ " 'children': [{'name': 'trash',\n",
+ " 'type': 'Trash',\n",
+ " 'size_x': 172.86,\n",
+ " 'size_y': 165.86,\n",
+ " 'size_z': 82,\n",
+ " 'location': {'x': 0, 'y': 0, 'z': 0, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'trash',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'trash_container',\n",
+ " 'max_volume': 'Infinity',\n",
+ " 'material_z_thickness': 0,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None}],\n",
+ " 'parent_name': 'deck'},\n",
+ " {'name': 'tiprack_1',\n",
+ " 'type': 'TipRack',\n",
+ " 'size_x': 127.76,\n",
+ " 'size_y': 85.48,\n",
+ " 'size_z': 64.49,\n",
+ " 'location': {'x': 0.0, 'y': 0.0, 'z': 0.0, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_rack',\n",
+ " 'model': 'Opentrons OT-2 96 Tip Rack 300 µL',\n",
+ " 'children': [{'name': 'tiprack_1_A1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_B1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_C1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_D1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_E1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_F1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_G1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_H1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_A2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_B2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_C2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_D2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_E2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_F2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_G2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_H2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_A3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_B3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_C3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_D3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_E3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_F3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_G3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_H3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_A4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_B4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_C4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_D4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_E4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_F4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_G4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_H4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_A5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_B5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_C5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_D5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_E5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_F5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_G5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_H5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_A6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_B6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_C6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_D6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_E6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_F6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_G6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_H6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_A7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_B7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_C7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_D7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_E7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_F7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_G7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_H7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_A8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_B8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_C8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_D8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_E8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_F8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_G8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_H8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_A9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_B9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_C9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_D9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_E9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_F9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_G9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_H9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_A10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_B10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_C10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_D10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_E10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_F10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_G10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_H10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_A11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 72.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_B11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 63.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_C11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 54.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_D11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 45.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_E11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 36.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_F11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 27.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_G11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 18.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_H11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_A12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 72.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_B12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 63.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_C12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 54.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_D12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 45.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_E12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 36.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_F12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 27.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_G12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 18.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_1_H12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_1',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}}],\n",
+ " 'parent_name': 'deck',\n",
+ " 'ordering': ['A1',\n",
+ " 'B1',\n",
+ " 'C1',\n",
+ " 'D1',\n",
+ " 'E1',\n",
+ " 'F1',\n",
+ " 'G1',\n",
+ " 'H1',\n",
+ " 'A2',\n",
+ " 'B2',\n",
+ " 'C2',\n",
+ " 'D2',\n",
+ " 'E2',\n",
+ " 'F2',\n",
+ " 'G2',\n",
+ " 'H2',\n",
+ " 'A3',\n",
+ " 'B3',\n",
+ " 'C3',\n",
+ " 'D3',\n",
+ " 'E3',\n",
+ " 'F3',\n",
+ " 'G3',\n",
+ " 'H3',\n",
+ " 'A4',\n",
+ " 'B4',\n",
+ " 'C4',\n",
+ " 'D4',\n",
+ " 'E4',\n",
+ " 'F4',\n",
+ " 'G4',\n",
+ " 'H4',\n",
+ " 'A5',\n",
+ " 'B5',\n",
+ " 'C5',\n",
+ " 'D5',\n",
+ " 'E5',\n",
+ " 'F5',\n",
+ " 'G5',\n",
+ " 'H5',\n",
+ " 'A6',\n",
+ " 'B6',\n",
+ " 'C6',\n",
+ " 'D6',\n",
+ " 'E6',\n",
+ " 'F6',\n",
+ " 'G6',\n",
+ " 'H6',\n",
+ " 'A7',\n",
+ " 'B7',\n",
+ " 'C7',\n",
+ " 'D7',\n",
+ " 'E7',\n",
+ " 'F7',\n",
+ " 'G7',\n",
+ " 'H7',\n",
+ " 'A8',\n",
+ " 'B8',\n",
+ " 'C8',\n",
+ " 'D8',\n",
+ " 'E8',\n",
+ " 'F8',\n",
+ " 'G8',\n",
+ " 'H8',\n",
+ " 'A9',\n",
+ " 'B9',\n",
+ " 'C9',\n",
+ " 'D9',\n",
+ " 'E9',\n",
+ " 'F9',\n",
+ " 'G9',\n",
+ " 'H9',\n",
+ " 'A10',\n",
+ " 'B10',\n",
+ " 'C10',\n",
+ " 'D10',\n",
+ " 'E10',\n",
+ " 'F10',\n",
+ " 'G10',\n",
+ " 'H10',\n",
+ " 'A11',\n",
+ " 'B11',\n",
+ " 'C11',\n",
+ " 'D11',\n",
+ " 'E11',\n",
+ " 'F11',\n",
+ " 'G11',\n",
+ " 'H11',\n",
+ " 'A12',\n",
+ " 'B12',\n",
+ " 'C12',\n",
+ " 'D12',\n",
+ " 'E12',\n",
+ " 'F12',\n",
+ " 'G12',\n",
+ " 'H12']},\n",
+ " {'name': 'tiprack_4',\n",
+ " 'type': 'TipRack',\n",
+ " 'size_x': 127.76,\n",
+ " 'size_y': 85.48,\n",
+ " 'size_z': 64.49,\n",
+ " 'location': {'x': 0.0, 'y': 90.5, 'z': 0.0, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_rack',\n",
+ " 'model': 'Opentrons OT-2 96 Tip Rack 300 µL',\n",
+ " 'children': [{'name': 'tiprack_4_A1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_B1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_C1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_D1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_E1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_F1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_G1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_H1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_A2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_B2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_C2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_D2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_E2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_F2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_G2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_H2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_A3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_B3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_C3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_D3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_E3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_F3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_G3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_H3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_A4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_B4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_C4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_D4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_E4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_F4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_G4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_H4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_A5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_B5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_C5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_D5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_E5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_F5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_G5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_H5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_A6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_B6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_C6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_D6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_E6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_F6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_G6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_H6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_A7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_B7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_C7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_D7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_E7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_F7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_G7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_H7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_A8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_B8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_C8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_D8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_E8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_F8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_G8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_H8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_A9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_B9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_C9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_D9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_E9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_F9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_G9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_H9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_A10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_B10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_C10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_D10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_E10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_F10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_G10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_H10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_A11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 72.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_B11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 63.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_C11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 54.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_D11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 45.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_E11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 36.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_F11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 27.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_G11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 18.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_H11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_A12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 72.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_B12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 63.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_C12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 54.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_D12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 45.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_E12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 36.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_F12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 27.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_G12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 18.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_4_H12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_4',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}}],\n",
+ " 'parent_name': 'deck',\n",
+ " 'ordering': ['A1',\n",
+ " 'B1',\n",
+ " 'C1',\n",
+ " 'D1',\n",
+ " 'E1',\n",
+ " 'F1',\n",
+ " 'G1',\n",
+ " 'H1',\n",
+ " 'A2',\n",
+ " 'B2',\n",
+ " 'C2',\n",
+ " 'D2',\n",
+ " 'E2',\n",
+ " 'F2',\n",
+ " 'G2',\n",
+ " 'H2',\n",
+ " 'A3',\n",
+ " 'B3',\n",
+ " 'C3',\n",
+ " 'D3',\n",
+ " 'E3',\n",
+ " 'F3',\n",
+ " 'G3',\n",
+ " 'H3',\n",
+ " 'A4',\n",
+ " 'B4',\n",
+ " 'C4',\n",
+ " 'D4',\n",
+ " 'E4',\n",
+ " 'F4',\n",
+ " 'G4',\n",
+ " 'H4',\n",
+ " 'A5',\n",
+ " 'B5',\n",
+ " 'C5',\n",
+ " 'D5',\n",
+ " 'E5',\n",
+ " 'F5',\n",
+ " 'G5',\n",
+ " 'H5',\n",
+ " 'A6',\n",
+ " 'B6',\n",
+ " 'C6',\n",
+ " 'D6',\n",
+ " 'E6',\n",
+ " 'F6',\n",
+ " 'G6',\n",
+ " 'H6',\n",
+ " 'A7',\n",
+ " 'B7',\n",
+ " 'C7',\n",
+ " 'D7',\n",
+ " 'E7',\n",
+ " 'F7',\n",
+ " 'G7',\n",
+ " 'H7',\n",
+ " 'A8',\n",
+ " 'B8',\n",
+ " 'C8',\n",
+ " 'D8',\n",
+ " 'E8',\n",
+ " 'F8',\n",
+ " 'G8',\n",
+ " 'H8',\n",
+ " 'A9',\n",
+ " 'B9',\n",
+ " 'C9',\n",
+ " 'D9',\n",
+ " 'E9',\n",
+ " 'F9',\n",
+ " 'G9',\n",
+ " 'H9',\n",
+ " 'A10',\n",
+ " 'B10',\n",
+ " 'C10',\n",
+ " 'D10',\n",
+ " 'E10',\n",
+ " 'F10',\n",
+ " 'G10',\n",
+ " 'H10',\n",
+ " 'A11',\n",
+ " 'B11',\n",
+ " 'C11',\n",
+ " 'D11',\n",
+ " 'E11',\n",
+ " 'F11',\n",
+ " 'G11',\n",
+ " 'H11',\n",
+ " 'A12',\n",
+ " 'B12',\n",
+ " 'C12',\n",
+ " 'D12',\n",
+ " 'E12',\n",
+ " 'F12',\n",
+ " 'G12',\n",
+ " 'H12']},\n",
+ " {'name': 'tiprack_8',\n",
+ " 'type': 'TipRack',\n",
+ " 'size_x': 127.76,\n",
+ " 'size_y': 85.48,\n",
+ " 'size_z': 64.49,\n",
+ " 'location': {'x': 132.5, 'y': 181.0, 'z': 0.0, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_rack',\n",
+ " 'model': 'Opentrons OT-2 96 Tip Rack 300 µL',\n",
+ " 'children': [{'name': 'tiprack_8_A1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_B1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_C1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_D1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_E1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_F1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_G1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_H1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_A2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_B2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_C2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_D2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_E2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_F2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_G2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_H2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_A3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_B3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_C3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_D3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_E3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_F3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_G3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_H3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_A4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_B4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_C4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_D4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_E4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_F4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_G4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_H4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_A5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_B5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_C5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_D5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_E5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_F5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_G5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_H5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_A6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_B6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_C6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_D6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_E6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_F6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_G6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_H6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_A7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_B7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_C7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_D7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_E7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_F7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_G7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_H7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_A8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_B8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_C8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_D8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_E8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_F8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_G8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_H8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_A9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_B9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_C9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_D9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_E9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_F9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_G9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_H9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_A10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_B10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_C10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_D10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_E10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_F10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_G10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_H10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_A11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 72.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_B11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 63.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_C11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 54.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_D11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 45.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_E11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 36.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_F11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 27.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_G11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 18.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_H11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_A12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 72.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_B12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 63.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_C12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 54.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_D12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 45.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_E12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 36.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_F12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 27.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_G12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 18.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_8_H12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_8',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}}],\n",
+ " 'parent_name': 'deck',\n",
+ " 'ordering': ['A1',\n",
+ " 'B1',\n",
+ " 'C1',\n",
+ " 'D1',\n",
+ " 'E1',\n",
+ " 'F1',\n",
+ " 'G1',\n",
+ " 'H1',\n",
+ " 'A2',\n",
+ " 'B2',\n",
+ " 'C2',\n",
+ " 'D2',\n",
+ " 'E2',\n",
+ " 'F2',\n",
+ " 'G2',\n",
+ " 'H2',\n",
+ " 'A3',\n",
+ " 'B3',\n",
+ " 'C3',\n",
+ " 'D3',\n",
+ " 'E3',\n",
+ " 'F3',\n",
+ " 'G3',\n",
+ " 'H3',\n",
+ " 'A4',\n",
+ " 'B4',\n",
+ " 'C4',\n",
+ " 'D4',\n",
+ " 'E4',\n",
+ " 'F4',\n",
+ " 'G4',\n",
+ " 'H4',\n",
+ " 'A5',\n",
+ " 'B5',\n",
+ " 'C5',\n",
+ " 'D5',\n",
+ " 'E5',\n",
+ " 'F5',\n",
+ " 'G5',\n",
+ " 'H5',\n",
+ " 'A6',\n",
+ " 'B6',\n",
+ " 'C6',\n",
+ " 'D6',\n",
+ " 'E6',\n",
+ " 'F6',\n",
+ " 'G6',\n",
+ " 'H6',\n",
+ " 'A7',\n",
+ " 'B7',\n",
+ " 'C7',\n",
+ " 'D7',\n",
+ " 'E7',\n",
+ " 'F7',\n",
+ " 'G7',\n",
+ " 'H7',\n",
+ " 'A8',\n",
+ " 'B8',\n",
+ " 'C8',\n",
+ " 'D8',\n",
+ " 'E8',\n",
+ " 'F8',\n",
+ " 'G8',\n",
+ " 'H8',\n",
+ " 'A9',\n",
+ " 'B9',\n",
+ " 'C9',\n",
+ " 'D9',\n",
+ " 'E9',\n",
+ " 'F9',\n",
+ " 'G9',\n",
+ " 'H9',\n",
+ " 'A10',\n",
+ " 'B10',\n",
+ " 'C10',\n",
+ " 'D10',\n",
+ " 'E10',\n",
+ " 'F10',\n",
+ " 'G10',\n",
+ " 'H10',\n",
+ " 'A11',\n",
+ " 'B11',\n",
+ " 'C11',\n",
+ " 'D11',\n",
+ " 'E11',\n",
+ " 'F11',\n",
+ " 'G11',\n",
+ " 'H11',\n",
+ " 'A12',\n",
+ " 'B12',\n",
+ " 'C12',\n",
+ " 'D12',\n",
+ " 'E12',\n",
+ " 'F12',\n",
+ " 'G12',\n",
+ " 'H12']},\n",
+ " {'name': 'tiprack_11',\n",
+ " 'type': 'TipRack',\n",
+ " 'size_x': 127.76,\n",
+ " 'size_y': 85.48,\n",
+ " 'size_z': 64.49,\n",
+ " 'location': {'x': 132.5, 'y': 271.5, 'z': 0.0, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_rack',\n",
+ " 'model': 'Opentrons OT-2 96 Tip Rack 300 µL',\n",
+ " 'children': [{'name': 'tiprack_11_A1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_B1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_C1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_D1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_E1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_F1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_G1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_H1',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 12.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_A2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_B2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_C2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_D2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_E2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_F2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_G2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_H2',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 21.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_A3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_B3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_C3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_D3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_E3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_F3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_G3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_H3',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 30.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_A4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_B4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_C4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_D4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_E4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_F4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_G4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_H4',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 39.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_A5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_B5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_C5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_D5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_E5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_F5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_G5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_H5',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 48.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_A6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_B6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_C6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_D6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_E6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_F6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_G6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_H6',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 57.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_A7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_B7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_C7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_D7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_E7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_F7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_G7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_H7',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 66.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_A8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_B8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_C8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_D8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_E8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_F8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_G8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_H8',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 75.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_A9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_B9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_C9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_D9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_E9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_F9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_G9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_H9',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 84.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_A10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 72.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_B10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 63.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_C10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 54.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_D10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 45.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_E10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 36.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_F10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 27.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_G10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 18.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_H10',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 93.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_A11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 72.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_B11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 63.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_C11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 54.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_D11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 45.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_E11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 36.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_F11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 27.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_G11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531,\n",
+ " 'y': 18.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_H11',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 102.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_A12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 72.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_B12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 63.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_C12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 54.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_D12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 45.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_E12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 36.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_F12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 27.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_G12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531,\n",
+ " 'y': 18.391,\n",
+ " 'z': 5.39,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}},\n",
+ " {'name': 'tiprack_11_H12',\n",
+ " 'type': 'TipSpot',\n",
+ " 'size_x': 3.698,\n",
+ " 'size_y': 3.698,\n",
+ " 'size_z': 0,\n",
+ " 'location': {'x': 111.531, 'y': 9.391, 'z': 5.39, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'tip_spot',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'tiprack_11',\n",
+ " 'prototype_tip': {'type': 'Tip',\n",
+ " 'total_tip_length': 59.3,\n",
+ " 'has_filter': False,\n",
+ " 'maximal_volume': 300.0,\n",
+ " 'fitting_depth': 7.47}}],\n",
+ " 'parent_name': 'deck',\n",
+ " 'ordering': ['A1',\n",
+ " 'B1',\n",
+ " 'C1',\n",
+ " 'D1',\n",
+ " 'E1',\n",
+ " 'F1',\n",
+ " 'G1',\n",
+ " 'H1',\n",
+ " 'A2',\n",
+ " 'B2',\n",
+ " 'C2',\n",
+ " 'D2',\n",
+ " 'E2',\n",
+ " 'F2',\n",
+ " 'G2',\n",
+ " 'H2',\n",
+ " 'A3',\n",
+ " 'B3',\n",
+ " 'C3',\n",
+ " 'D3',\n",
+ " 'E3',\n",
+ " 'F3',\n",
+ " 'G3',\n",
+ " 'H3',\n",
+ " 'A4',\n",
+ " 'B4',\n",
+ " 'C4',\n",
+ " 'D4',\n",
+ " 'E4',\n",
+ " 'F4',\n",
+ " 'G4',\n",
+ " 'H4',\n",
+ " 'A5',\n",
+ " 'B5',\n",
+ " 'C5',\n",
+ " 'D5',\n",
+ " 'E5',\n",
+ " 'F5',\n",
+ " 'G5',\n",
+ " 'H5',\n",
+ " 'A6',\n",
+ " 'B6',\n",
+ " 'C6',\n",
+ " 'D6',\n",
+ " 'E6',\n",
+ " 'F6',\n",
+ " 'G6',\n",
+ " 'H6',\n",
+ " 'A7',\n",
+ " 'B7',\n",
+ " 'C7',\n",
+ " 'D7',\n",
+ " 'E7',\n",
+ " 'F7',\n",
+ " 'G7',\n",
+ " 'H7',\n",
+ " 'A8',\n",
+ " 'B8',\n",
+ " 'C8',\n",
+ " 'D8',\n",
+ " 'E8',\n",
+ " 'F8',\n",
+ " 'G8',\n",
+ " 'H8',\n",
+ " 'A9',\n",
+ " 'B9',\n",
+ " 'C9',\n",
+ " 'D9',\n",
+ " 'E9',\n",
+ " 'F9',\n",
+ " 'G9',\n",
+ " 'H9',\n",
+ " 'A10',\n",
+ " 'B10',\n",
+ " 'C10',\n",
+ " 'D10',\n",
+ " 'E10',\n",
+ " 'F10',\n",
+ " 'G10',\n",
+ " 'H10',\n",
+ " 'A11',\n",
+ " 'B11',\n",
+ " 'C11',\n",
+ " 'D11',\n",
+ " 'E11',\n",
+ " 'F11',\n",
+ " 'G11',\n",
+ " 'H11',\n",
+ " 'A12',\n",
+ " 'B12',\n",
+ " 'C12',\n",
+ " 'D12',\n",
+ " 'E12',\n",
+ " 'F12',\n",
+ " 'G12',\n",
+ " 'H12']},\n",
+ " {'name': 'working_plate',\n",
+ " 'type': 'Plate',\n",
+ " 'size_x': 127.76,\n",
+ " 'size_y': 85.47,\n",
+ " 'size_z': 14.22,\n",
+ " 'location': {'x': 265.0, 'y': 90.5, 'z': 0.0, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'plate',\n",
+ " 'model': 'Corning 96 Well Plate 360 µL Flat',\n",
+ " 'children': [{'name': 'working_plate_A1',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 11.9545,\n",
+ " 'y': 71.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_B1',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 11.9545,\n",
+ " 'y': 62.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_C1',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 11.9545,\n",
+ " 'y': 53.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_D1',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 11.9545,\n",
+ " 'y': 44.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_E1',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 11.9545,\n",
+ " 'y': 35.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_F1',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 11.9545,\n",
+ " 'y': 26.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_G1',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 11.9545,\n",
+ " 'y': 17.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_H1',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 11.9545,\n",
+ " 'y': 8.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_A2',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 20.9545,\n",
+ " 'y': 71.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_B2',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 20.9545,\n",
+ " 'y': 62.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_C2',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 20.9545,\n",
+ " 'y': 53.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_D2',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 20.9545,\n",
+ " 'y': 44.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_E2',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 20.9545,\n",
+ " 'y': 35.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_F2',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 20.9545,\n",
+ " 'y': 26.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_G2',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 20.9545,\n",
+ " 'y': 17.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_H2',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 20.9545,\n",
+ " 'y': 8.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_A3',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 29.9545,\n",
+ " 'y': 71.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_B3',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 29.9545,\n",
+ " 'y': 62.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_C3',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 29.9545,\n",
+ " 'y': 53.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_D3',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 29.9545,\n",
+ " 'y': 44.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_E3',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 29.9545,\n",
+ " 'y': 35.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_F3',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 29.9545,\n",
+ " 'y': 26.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_G3',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 29.9545,\n",
+ " 'y': 17.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_H3',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 29.9545,\n",
+ " 'y': 8.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_A4',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 38.9545,\n",
+ " 'y': 71.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_B4',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 38.9545,\n",
+ " 'y': 62.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_C4',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 38.9545,\n",
+ " 'y': 53.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_D4',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 38.9545,\n",
+ " 'y': 44.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_E4',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 38.9545,\n",
+ " 'y': 35.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_F4',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 38.9545,\n",
+ " 'y': 26.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_G4',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 38.9545,\n",
+ " 'y': 17.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_H4',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 38.9545,\n",
+ " 'y': 8.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_A5',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 47.9545,\n",
+ " 'y': 71.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_B5',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 47.9545,\n",
+ " 'y': 62.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_C5',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 47.9545,\n",
+ " 'y': 53.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_D5',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 47.9545,\n",
+ " 'y': 44.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_E5',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 47.9545,\n",
+ " 'y': 35.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_F5',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 47.9545,\n",
+ " 'y': 26.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_G5',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 47.9545,\n",
+ " 'y': 17.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_H5',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 47.9545,\n",
+ " 'y': 8.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_A6',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 56.9545,\n",
+ " 'y': 71.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_B6',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 56.9545,\n",
+ " 'y': 62.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_C6',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 56.9545,\n",
+ " 'y': 53.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_D6',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 56.9545,\n",
+ " 'y': 44.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_E6',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 56.9545,\n",
+ " 'y': 35.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_F6',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 56.9545,\n",
+ " 'y': 26.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_G6',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 56.9545,\n",
+ " 'y': 17.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_H6',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 56.9545,\n",
+ " 'y': 8.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_A7',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 65.9545,\n",
+ " 'y': 71.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_B7',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 65.9545,\n",
+ " 'y': 62.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_C7',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 65.9545,\n",
+ " 'y': 53.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_D7',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 65.9545,\n",
+ " 'y': 44.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_E7',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 65.9545,\n",
+ " 'y': 35.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_F7',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 65.9545,\n",
+ " 'y': 26.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_G7',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 65.9545,\n",
+ " 'y': 17.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_H7',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 65.9545,\n",
+ " 'y': 8.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_A8',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 74.9545,\n",
+ " 'y': 71.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_B8',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 74.9545,\n",
+ " 'y': 62.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_C8',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 74.9545,\n",
+ " 'y': 53.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_D8',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 74.9545,\n",
+ " 'y': 44.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_E8',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 74.9545,\n",
+ " 'y': 35.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_F8',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 74.9545,\n",
+ " 'y': 26.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_G8',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 74.9545,\n",
+ " 'y': 17.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_H8',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 74.9545,\n",
+ " 'y': 8.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_A9',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 83.9545,\n",
+ " 'y': 71.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_B9',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 83.9545,\n",
+ " 'y': 62.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_C9',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 83.9545,\n",
+ " 'y': 53.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_D9',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 83.9545,\n",
+ " 'y': 44.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_E9',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 83.9545,\n",
+ " 'y': 35.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_F9',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 83.9545,\n",
+ " 'y': 26.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_G9',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 83.9545,\n",
+ " 'y': 17.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_H9',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 83.9545,\n",
+ " 'y': 8.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_A10',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 92.9545,\n",
+ " 'y': 71.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_B10',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 92.9545,\n",
+ " 'y': 62.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_C10',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 92.9545,\n",
+ " 'y': 53.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_D10',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 92.9545,\n",
+ " 'y': 44.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_E10',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 92.9545,\n",
+ " 'y': 35.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_F10',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 92.9545,\n",
+ " 'y': 26.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_G10',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 92.9545,\n",
+ " 'y': 17.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_H10',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 92.9545,\n",
+ " 'y': 8.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_A11',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 101.9545,\n",
+ " 'y': 71.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_B11',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 101.9545,\n",
+ " 'y': 62.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_C11',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 101.9545,\n",
+ " 'y': 53.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_D11',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 101.9545,\n",
+ " 'y': 44.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_E11',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 101.9545,\n",
+ " 'y': 35.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_F11',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 101.9545,\n",
+ " 'y': 26.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_G11',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 101.9545,\n",
+ " 'y': 17.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_H11',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 101.9545,\n",
+ " 'y': 8.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_A12',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 110.9545,\n",
+ " 'y': 71.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_B12',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 110.9545,\n",
+ " 'y': 62.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_C12',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 110.9545,\n",
+ " 'y': 53.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_D12',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 110.9545,\n",
+ " 'y': 44.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_E12',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 110.9545,\n",
+ " 'y': 35.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_F12',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 110.9545,\n",
+ " 'y': 26.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_G12',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 110.9545,\n",
+ " 'y': 17.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'},\n",
+ " {'name': 'working_plate_H12',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 4.851,\n",
+ " 'size_y': 4.851,\n",
+ " 'size_z': 10.67,\n",
+ " 'location': {'x': 110.9545,\n",
+ " 'y': 8.8145,\n",
+ " 'z': 3.55,\n",
+ " 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'working_plate',\n",
+ " 'max_volume': 360,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'circle'}],\n",
+ " 'parent_name': 'deck',\n",
+ " 'ordering': ['A1',\n",
+ " 'B1',\n",
+ " 'C1',\n",
+ " 'D1',\n",
+ " 'E1',\n",
+ " 'F1',\n",
+ " 'G1',\n",
+ " 'H1',\n",
+ " 'A2',\n",
+ " 'B2',\n",
+ " 'C2',\n",
+ " 'D2',\n",
+ " 'E2',\n",
+ " 'F2',\n",
+ " 'G2',\n",
+ " 'H2',\n",
+ " 'A3',\n",
+ " 'B3',\n",
+ " 'C3',\n",
+ " 'D3',\n",
+ " 'E3',\n",
+ " 'F3',\n",
+ " 'G3',\n",
+ " 'H3',\n",
+ " 'A4',\n",
+ " 'B4',\n",
+ " 'C4',\n",
+ " 'D4',\n",
+ " 'E4',\n",
+ " 'F4',\n",
+ " 'G4',\n",
+ " 'H4',\n",
+ " 'A5',\n",
+ " 'B5',\n",
+ " 'C5',\n",
+ " 'D5',\n",
+ " 'E5',\n",
+ " 'F5',\n",
+ " 'G5',\n",
+ " 'H5',\n",
+ " 'A6',\n",
+ " 'B6',\n",
+ " 'C6',\n",
+ " 'D6',\n",
+ " 'E6',\n",
+ " 'F6',\n",
+ " 'G6',\n",
+ " 'H6',\n",
+ " 'A7',\n",
+ " 'B7',\n",
+ " 'C7',\n",
+ " 'D7',\n",
+ " 'E7',\n",
+ " 'F7',\n",
+ " 'G7',\n",
+ " 'H7',\n",
+ " 'A8',\n",
+ " 'B8',\n",
+ " 'C8',\n",
+ " 'D8',\n",
+ " 'E8',\n",
+ " 'F8',\n",
+ " 'G8',\n",
+ " 'H8',\n",
+ " 'A9',\n",
+ " 'B9',\n",
+ " 'C9',\n",
+ " 'D9',\n",
+ " 'E9',\n",
+ " 'F9',\n",
+ " 'G9',\n",
+ " 'H9',\n",
+ " 'A10',\n",
+ " 'B10',\n",
+ " 'C10',\n",
+ " 'D10',\n",
+ " 'E10',\n",
+ " 'F10',\n",
+ " 'G10',\n",
+ " 'H10',\n",
+ " 'A11',\n",
+ " 'B11',\n",
+ " 'C11',\n",
+ " 'D11',\n",
+ " 'E11',\n",
+ " 'F11',\n",
+ " 'G11',\n",
+ " 'H11',\n",
+ " 'A12',\n",
+ " 'B12',\n",
+ " 'C12',\n",
+ " 'D12',\n",
+ " 'E12',\n",
+ " 'F12',\n",
+ " 'G12',\n",
+ " 'H12']},\n",
+ " {'name': 'reagent_stock',\n",
+ " 'type': 'Plate',\n",
+ " 'size_x': 127.76,\n",
+ " 'size_y': 85.48,\n",
+ " 'size_z': 31.4,\n",
+ " 'location': {'x': 265.0, 'y': 0.0, 'z': 0.0, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'plate',\n",
+ " 'model': 'NEST 12 Well Reservoir 15 mL',\n",
+ " 'children': [{'name': 'reagent_stock_A1',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 8.2,\n",
+ " 'size_y': 71.2,\n",
+ " 'size_z': 26.85,\n",
+ " 'location': {'x': 10.28, 'y': 7.18, 'z': 4.55, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'reagent_stock',\n",
+ " 'max_volume': 15000,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'rectangle'},\n",
+ " {'name': 'reagent_stock_A2',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 8.2,\n",
+ " 'size_y': 71.2,\n",
+ " 'size_z': 26.85,\n",
+ " 'location': {'x': 19.28, 'y': 7.18, 'z': 4.55, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'reagent_stock',\n",
+ " 'max_volume': 15000,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'rectangle'},\n",
+ " {'name': 'reagent_stock_A3',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 8.2,\n",
+ " 'size_y': 71.2,\n",
+ " 'size_z': 26.85,\n",
+ " 'location': {'x': 28.28, 'y': 7.18, 'z': 4.55, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'reagent_stock',\n",
+ " 'max_volume': 15000,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'rectangle'},\n",
+ " {'name': 'reagent_stock_A4',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 8.2,\n",
+ " 'size_y': 71.2,\n",
+ " 'size_z': 26.85,\n",
+ " 'location': {'x': 37.28, 'y': 7.18, 'z': 4.55, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'reagent_stock',\n",
+ " 'max_volume': 15000,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'rectangle'},\n",
+ " {'name': 'reagent_stock_A5',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 8.2,\n",
+ " 'size_y': 71.2,\n",
+ " 'size_z': 26.85,\n",
+ " 'location': {'x': 46.28, 'y': 7.18, 'z': 4.55, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'reagent_stock',\n",
+ " 'max_volume': 15000,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'rectangle'},\n",
+ " {'name': 'reagent_stock_A6',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 8.2,\n",
+ " 'size_y': 71.2,\n",
+ " 'size_z': 26.85,\n",
+ " 'location': {'x': 55.28, 'y': 7.18, 'z': 4.55, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'reagent_stock',\n",
+ " 'max_volume': 15000,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'rectangle'},\n",
+ " {'name': 'reagent_stock_A7',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 8.2,\n",
+ " 'size_y': 71.2,\n",
+ " 'size_z': 26.85,\n",
+ " 'location': {'x': 64.28, 'y': 7.18, 'z': 4.55, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'reagent_stock',\n",
+ " 'max_volume': 15000,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'rectangle'},\n",
+ " {'name': 'reagent_stock_A8',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 8.2,\n",
+ " 'size_y': 71.2,\n",
+ " 'size_z': 26.85,\n",
+ " 'location': {'x': 73.28, 'y': 7.18, 'z': 4.55, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'reagent_stock',\n",
+ " 'max_volume': 15000,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'rectangle'},\n",
+ " {'name': 'reagent_stock_A9',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 8.2,\n",
+ " 'size_y': 71.2,\n",
+ " 'size_z': 26.85,\n",
+ " 'location': {'x': 82.28, 'y': 7.18, 'z': 4.55, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'reagent_stock',\n",
+ " 'max_volume': 15000,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'rectangle'},\n",
+ " {'name': 'reagent_stock_A10',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 8.2,\n",
+ " 'size_y': 71.2,\n",
+ " 'size_z': 26.85,\n",
+ " 'location': {'x': 91.28, 'y': 7.18, 'z': 4.55, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'reagent_stock',\n",
+ " 'max_volume': 15000,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'rectangle'},\n",
+ " {'name': 'reagent_stock_A11',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 8.2,\n",
+ " 'size_y': 71.2,\n",
+ " 'size_z': 26.85,\n",
+ " 'location': {'x': 100.28, 'y': 7.18, 'z': 4.55, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'reagent_stock',\n",
+ " 'max_volume': 15000,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'rectangle'},\n",
+ " {'name': 'reagent_stock_A12',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 8.2,\n",
+ " 'size_y': 71.2,\n",
+ " 'size_z': 26.85,\n",
+ " 'location': {'x': 109.28, 'y': 7.18, 'z': 4.55, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'reagent_stock',\n",
+ " 'max_volume': 15000,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'rectangle'}],\n",
+ " 'parent_name': 'deck',\n",
+ " 'ordering': ['A1',\n",
+ " 'A2',\n",
+ " 'A3',\n",
+ " 'A4',\n",
+ " 'A5',\n",
+ " 'A6',\n",
+ " 'A7',\n",
+ " 'A8',\n",
+ " 'A9',\n",
+ " 'A10',\n",
+ " 'A11',\n",
+ " 'A12']},\n",
+ " {'name': 'waste_liq',\n",
+ " 'type': 'Plate',\n",
+ " 'size_x': 127.76,\n",
+ " 'size_y': 85.48,\n",
+ " 'size_z': 31.4,\n",
+ " 'location': {'x': 265.0, 'y': 181.0, 'z': 0.0, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'plate',\n",
+ " 'model': 'NEST 1 Well Reservoir 195 mL',\n",
+ " 'children': [{'name': 'waste_liq_A1',\n",
+ " 'type': 'Well',\n",
+ " 'size_x': 106.8,\n",
+ " 'size_y': 71.2,\n",
+ " 'size_z': 25,\n",
+ " 'location': {'x': 10.48, 'y': 7.14, 'z': 4.55, 'type': 'Coordinate'},\n",
+ " 'rotation': {'x': 0, 'y': 0, 'z': 0, 'type': 'Rotation'},\n",
+ " 'category': 'well',\n",
+ " 'model': None,\n",
+ " 'children': [],\n",
+ " 'parent_name': 'waste_liq',\n",
+ " 'max_volume': 195000,\n",
+ " 'material_z_thickness': None,\n",
+ " 'compute_volume_from_height': None,\n",
+ " 'compute_height_from_volume': None,\n",
+ " 'bottom_type': 'unknown',\n",
+ " 'cross_section_type': 'rectangle'}],\n",
+ " 'parent_name': 'deck',\n",
+ " 'ordering': ['A1']}],\n",
+ " 'parent_name': 'lh_deck'}],\n",
+ " 'parent_name': None,\n",
+ " 'backend': {'type': 'LiquidHandlerChatterboxBackend', 'num_channels': 8}}"
+ ]
+ },
+ "execution_count": 6,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "execution_count": 6
},
{
"cell_type": "code",
- "execution_count": 14,
"id": "70094125",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Picking up tips:\n",
- "pip# resource offset tip type max volume (µL) fitting depth (mm) tip length (mm) filter \n",
- " p0: tiprack_1_A1 0,0,0 Tip 300.0 7.47 59.3 No \n",
- "Aspirating:\n",
- "pip# vol(ul) resource offset flow rate blowout lld_z \n",
- " p0: 100.0 working_plate_A1 -2.5,0,0 0.2 None 0.2 \n",
- "[Well(name=waste_liq_A1, location=Coordinate(010.480, 007.140, 004.550), size_x=106.8, size_y=71.2, size_z=25, category=well)]\n",
- "Dispensing:\n",
- "pip# vol(ul) resource offset flow rate blowout lld_z \n",
- " p0: 100.0 waste_liq_A1 0,0,-5 3.0 None 0.0 \n",
- "Dropping tips:\n",
- "pip# resource offset tip type max volume (µL) fitting depth (mm) tip length (mm) filter \n",
- " p0: trash 0,0.0,0 Tip 300.0 7.47 59.3 No \n",
- "Picking up tips:\n",
- "pip# resource offset tip type max volume (µL) fitting depth (mm) tip length (mm) filter \n",
- " p0: tiprack_1_B1 0,0,0 Tip 300.0 7.47 59.3 No \n",
- "Aspirating:\n",
- "pip# vol(ul) resource offset flow rate blowout lld_z \n",
- " p0: 100.0 working_plate_A2 -2.5,0,0 0.2 None 0.2 \n",
- "[Well(name=waste_liq_A1, location=Coordinate(010.480, 007.140, 004.550), size_x=106.8, size_y=71.2, size_z=25, category=well)]\n",
- "Dispensing:\n",
- "pip# vol(ul) resource offset flow rate blowout lld_z \n",
- " p0: 100.0 waste_liq_A1 0,0,-5 3.0 None 0.0 \n",
- "Dropping tips:\n",
- "pip# resource offset tip type max volume (µL) fitting depth (mm) tip length (mm) filter \n",
- " p0: trash 0,0.0,0 Tip 300.0 7.47 59.3 No \n",
- "Picking up tips:\n",
- "pip# resource offset tip type max volume (µL) fitting depth (mm) tip length (mm) filter \n",
- " p0: tiprack_1_C1 0,0,0 Tip 300.0 7.47 59.3 No \n",
- "Aspirating:\n",
- "pip# vol(ul) resource offset flow rate blowout lld_z \n",
- " p0: 100.0 working_plate_A3 -2.5,0,0 0.2 None 0.2 \n",
- "[Well(name=waste_liq_A1, location=Coordinate(010.480, 007.140, 004.550), size_x=106.8, size_y=71.2, size_z=25, category=well)]\n",
- "Dispensing:\n",
- "pip# vol(ul) resource offset flow rate blowout lld_z \n",
- " p0: 100.0 waste_liq_A1 0,0,-5 3.0 None 0.0 \n",
- "Dropping tips:\n",
- "pip# resource offset tip type max volume (µL) fitting depth (mm) tip length (mm) filter \n",
- " p0: trash 0,0.0,0 Tip 300.0 7.47 59.3 No \n",
- "Picking up tips:\n",
- "pip# resource offset tip type max volume (µL) fitting depth (mm) tip length (mm) filter \n",
- " p0: tiprack_1_D1 0,0,0 Tip 300.0 7.47 59.3 No \n",
- "Aspirating:\n",
- "pip# vol(ul) resource offset flow rate blowout lld_z \n",
- " p0: 100.0 working_plate_A4 -2.5,0,0 0.2 None 0.2 \n",
- "[Well(name=waste_liq_A1, location=Coordinate(010.480, 007.140, 004.550), size_x=106.8, size_y=71.2, size_z=25, category=well)]\n",
- "Dispensing:\n",
- "pip# vol(ul) resource offset flow rate blowout lld_z \n",
- " p0: 100.0 waste_liq_A1 0,0,-5 3.0 None 0.0 \n",
- "Dropping tips:\n",
- "pip# resource offset tip type max volume (µL) fitting depth (mm) tip length (mm) filter \n",
- " p0: trash 0,0.0,0 Tip 300.0 7.47 59.3 No \n",
- "Picking up tips:\n",
- "pip# resource offset tip type max volume (µL) fitting depth (mm) tip length (mm) filter \n",
- " p0: tiprack_1_E1 0,0,0 Tip 300.0 7.47 59.3 No \n",
- "Aspirating:\n",
- "pip# vol(ul) resource offset flow rate blowout lld_z \n",
- " p0: 100.0 working_plate_A5 -2.5,0,0 0.2 None 0.2 \n",
- "[Well(name=waste_liq_A1, location=Coordinate(010.480, 007.140, 004.550), size_x=106.8, size_y=71.2, size_z=25, category=well)]\n",
- "Dispensing:\n",
- "pip# vol(ul) resource offset flow rate blowout lld_z \n",
- " p0: 100.0 waste_liq_A1 0,0,-5 3.0 None 0.0 \n",
- "Dropping tips:\n",
- "pip# resource offset tip type max volume (µL) fitting depth (mm) tip length (mm) filter \n",
- " p0: trash 0,0.0,0 Tip 300.0 7.47 59.3 No \n",
- "Picking up tips:\n",
- "pip# resource offset tip type max volume (µL) fitting depth (mm) tip length (mm) filter \n",
- " p0: tiprack_1_F1 0,0,0 Tip 300.0 7.47 59.3 No \n",
- "Aspirating:\n",
- "pip# vol(ul) resource offset flow rate blowout lld_z \n",
- " p0: 100.0 working_plate_A6 -2.5,0,0 0.2 None 0.2 \n",
- "[Well(name=waste_liq_A1, location=Coordinate(010.480, 007.140, 004.550), size_x=106.8, size_y=71.2, size_z=25, category=well)]\n",
- "Dispensing:\n",
- "pip# vol(ul) resource offset flow rate blowout lld_z \n",
- " p0: 100.0 waste_liq_A1 0,0,-5 3.0 None 0.0 \n",
- "Dropping tips:\n",
- "pip# resource offset tip type max volume (µL) fitting depth (mm) tip length (mm) filter \n",
- " p0: trash 0,0.0,0 Tip 300.0 7.47 59.3 No \n",
- "Picking up tips:\n",
- "pip# resource offset tip type max volume (µL) fitting depth (mm) tip length (mm) filter \n",
- " p0: tiprack_1_G1 0,0,0 Tip 300.0 7.47 59.3 No \n",
- "Aspirating:\n",
- "pip# vol(ul) resource offset flow rate blowout lld_z \n",
- " p0: 100.0 working_plate_A7 -2.5,0,0 0.2 None 0.2 \n",
- "[Well(name=waste_liq_A1, location=Coordinate(010.480, 007.140, 004.550), size_x=106.8, size_y=71.2, size_z=25, category=well)]\n",
- "Dispensing:\n",
- "pip# vol(ul) resource offset flow rate blowout lld_z \n",
- " p0: 100.0 waste_liq_A1 0,0,-5 3.0 None 0.0 \n",
- "Dropping tips:\n",
- "pip# resource offset tip type max volume (µL) fitting depth (mm) tip length (mm) filter \n",
- " p0: trash 0,0.0,0 Tip 300.0 7.47 59.3 No \n",
- "Picking up tips:\n",
- "pip# resource offset tip type max volume (µL) fitting depth (mm) tip length (mm) filter \n",
- " p0: tiprack_1_H1 0,0,0 Tip 300.0 7.47 59.3 No \n",
- "Aspirating:\n",
- "pip# vol(ul) resource offset flow rate blowout lld_z \n",
- " p0: 100.0 working_plate_A8 -2.5,0,0 0.2 None 0.2 \n",
- "[Well(name=waste_liq_A1, location=Coordinate(010.480, 007.140, 004.550), size_x=106.8, size_y=71.2, size_z=25, category=well)]\n",
- "Dispensing:\n",
- "pip# vol(ul) resource offset flow rate blowout lld_z \n",
- " p0: 100.0 waste_liq_A1 0,0,-5 3.0 None 0.0 \n",
- "Dropping tips:\n",
- "pip# resource offset tip type max volume (µL) fitting depth (mm) tip length (mm) filter \n",
- " p0: trash 0,0.0,0 Tip 300.0 7.47 59.3 No \n",
- "Picking up tips:\n",
- "pip# resource offset tip type max volume (µL) fitting depth (mm) tip length (mm) filter \n",
- " p0: tiprack_1_A2 0,0,0 Tip 300.0 7.47 59.3 No \n",
- "Aspirating:\n",
- "pip# vol(ul) resource offset flow rate blowout lld_z \n",
- " p0: 100.0 working_plate_A9 -2.5,0,0 0.2 None 0.2 \n",
- "[Well(name=waste_liq_A1, location=Coordinate(010.480, 007.140, 004.550), size_x=106.8, size_y=71.2, size_z=25, category=well)]\n",
- "Dispensing:\n",
- "pip# vol(ul) resource offset flow rate blowout lld_z \n",
- " p0: 100.0 waste_liq_A1 0,0,-5 3.0 None 0.0 \n",
- "Dropping tips:\n",
- "pip# resource offset tip type max volume (µL) fitting depth (mm) tip length (mm) filter \n",
- " p0: trash 0,0.0,0 Tip 300.0 7.47 59.3 No \n",
- "Picking up tips:\n",
- "pip# resource offset tip type max volume (µL) fitting depth (mm) tip length (mm) filter \n",
- " p0: tiprack_1_B2 0,0,0 Tip 300.0 7.47 59.3 No \n",
- "Aspirating:\n",
- "pip# vol(ul) resource offset flow rate blowout lld_z \n",
- " p0: 100.0 working_plate_A10 -2.5,0,0 0.2 None 0.2 \n",
- "[Well(name=waste_liq_A1, location=Coordinate(010.480, 007.140, 004.550), size_x=106.8, size_y=71.2, size_z=25, category=well)]\n",
- "Dispensing:\n",
- "pip# vol(ul) resource offset flow rate blowout lld_z \n",
- " p0: 100.0 waste_liq_A1 0,0,-5 3.0 None 0.0 \n",
- "Dropping tips:\n",
- "pip# resource offset tip type max volume (µL) fitting depth (mm) tip length (mm) filter \n",
- " p0: trash 0,0.0,0 Tip 300.0 7.47 59.3 No \n",
- "Picking up tips:\n",
- "pip# resource offset tip type max volume (µL) fitting depth (mm) tip length (mm) filter \n",
- " p0: tiprack_1_C2 0,0,0 Tip 300.0 7.47 59.3 No \n",
- "Aspirating:\n",
- "pip# vol(ul) resource offset flow rate blowout lld_z \n",
- " p0: 100.0 working_plate_A11 -2.5,0,0 0.2 None 0.2 \n",
- "[Well(name=waste_liq_A1, location=Coordinate(010.480, 007.140, 004.550), size_x=106.8, size_y=71.2, size_z=25, category=well)]\n",
- "Dispensing:\n",
- "pip# vol(ul) resource offset flow rate blowout lld_z \n",
- " p0: 100.0 waste_liq_A1 0,0,-5 3.0 None 0.0 \n",
- "Dropping tips:\n",
- "pip# resource offset tip type max volume (µL) fitting depth (mm) tip length (mm) filter \n",
- " p0: trash 0,0.0,0 Tip 300.0 7.47 59.3 No \n",
- "Picking up tips:\n",
- "pip# resource offset tip type max volume (µL) fitting depth (mm) tip length (mm) filter \n",
- " p0: tiprack_1_D2 0,0,0 Tip 300.0 7.47 59.3 No \n",
- "Aspirating:\n",
- "pip# vol(ul) resource offset flow rate blowout lld_z \n",
- " p0: 100.0 working_plate_A12 -2.5,0,0 0.2 None 0.2 \n",
- "[Well(name=waste_liq_A1, location=Coordinate(010.480, 007.140, 004.550), size_x=106.8, size_y=71.2, size_z=25, category=well)]\n",
- "Dispensing:\n",
- "pip# vol(ul) resource offset flow rate blowout lld_z \n",
- " p0: 100.0 waste_liq_A1 0,0,-5 3.0 None 0.0 \n",
- "Dropping tips:\n",
- "pip# resource offset tip type max volume (µL) fitting depth (mm) tip length (mm) filter \n",
- " p0: trash 0,0.0,0 Tip 300.0 7.47 59.3 No \n"
- ]
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2025-06-08T14:25:19.507693Z",
+ "start_time": "2025-06-08T14:25:18.487272Z"
}
- ],
+ },
"source": [
"await lh.remove_liquid(\n",
" vols=[MEDIUM_VOL]*12,\n",
@@ -323,7 +9304,21 @@
" flow_rates=[0.2,3],\n",
" offsets=[Coordinate(-2.5, 0, 0),Coordinate(0, 0, -5)]\n",
")"
- ]
+ ],
+ "outputs": [
+ {
+ "ename": "AttributeError",
+ "evalue": "'LiquidHandler' object has no attribute 'remove_liquid'",
+ "output_type": "error",
+ "traceback": [
+ "\u001B[31m---------------------------------------------------------------------------\u001B[39m",
+ "\u001B[31mAttributeError\u001B[39m Traceback (most recent call last)",
+ "\u001B[36mCell\u001B[39m\u001B[36m \u001B[39m\u001B[32mIn[6]\u001B[39m\u001B[32m, line 1\u001B[39m\n\u001B[32m----> \u001B[39m\u001B[32m1\u001B[39m \u001B[38;5;28;01mawait\u001B[39;00m \u001B[43mlh\u001B[49m\u001B[43m.\u001B[49m\u001B[43mremove_liquid\u001B[49m(\n\u001B[32m 2\u001B[39m vols=[MEDIUM_VOL]*\u001B[32m12\u001B[39m,\n\u001B[32m 3\u001B[39m sources=cells_all,\n\u001B[32m 4\u001B[39m waste_liquid=waste_liq,\n\u001B[32m 5\u001B[39m top=[-\u001B[32m0.2\u001B[39m],\n\u001B[32m 6\u001B[39m liquid_height=[\u001B[32m0.2\u001B[39m,\u001B[32m0\u001B[39m],\n\u001B[32m 7\u001B[39m flow_rates=[\u001B[32m0.2\u001B[39m,\u001B[32m3\u001B[39m],\n\u001B[32m 8\u001B[39m offsets=[Coordinate(-\u001B[32m2.5\u001B[39m, \u001B[32m0\u001B[39m, \u001B[32m0\u001B[39m),Coordinate(\u001B[32m0\u001B[39m, \u001B[32m0\u001B[39m, -\u001B[32m5\u001B[39m)]\n\u001B[32m 9\u001B[39m )\n",
+ "\u001B[31mAttributeError\u001B[39m: 'LiquidHandler' object has no attribute 'remove_liquid'"
+ ]
+ }
+ ],
+ "execution_count": 6
},
{
"cell_type": "code",
diff --git a/unilabos/devices/resource_container/__init__.py b/unilabos/devices/resource_container/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/unilabos/devices/resource_container/container.py b/unilabos/devices/resource_container/container.py
new file mode 100644
index 0000000..38b9a80
--- /dev/null
+++ b/unilabos/devices/resource_container/container.py
@@ -0,0 +1,9 @@
+
+class HotelContainer:
+ def __init__(self, rotation: dict, device_config: dict):
+ self.rotation = rotation
+ self.device_config = device_config
+ self.status = 'idle'
+
+ def get_rotation(self):
+ return self.rotation
diff --git a/unilabos/devices/ros_dev/lh_joint_config.json b/unilabos/devices/ros_dev/lh_joint_config.json
new file mode 100644
index 0000000..908cc54
--- /dev/null
+++ b/unilabos/devices/ros_dev/lh_joint_config.json
@@ -0,0 +1,38 @@
+{
+ "OTDeck":{
+ "joint_names":[
+ "first_joint",
+ "second_joint",
+ "third_joint",
+ "fourth_joint"
+ ],
+ "link_names":[
+ "first_link",
+ "second_link",
+ "third_link",
+ "fourth_link"
+ ],
+ "y":{
+ "first_joint":{
+ "factor":-0.001,
+ "offset":0.166
+ }
+ },
+ "x":{
+ "second_joint":{
+ "factor":-0.001,
+ "offset":0.1775
+ }
+ },
+ "z":{
+ "third_joint":{
+ "factor":0.001,
+ "offset":0.0
+ },
+ "fourth_joint":{
+ "factor":0.001,
+ "offset":0.0
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/unilabos/devices/ros_dev/liquid_handler_joint_publisher.py b/unilabos/devices/ros_dev/liquid_handler_joint_publisher.py
index e593f42..882b519 100644
--- a/unilabos/devices/ros_dev/liquid_handler_joint_publisher.py
+++ b/unilabos/devices/ros_dev/liquid_handler_joint_publisher.py
@@ -1,9 +1,12 @@
+import asyncio
import copy
+from pathlib import Path
+import threading
import rclpy
import json
import time
from rclpy.executors import MultiThreadedExecutor
-from rclpy.action import ActionServer
+from rclpy.action import ActionServer,ActionClient
from sensor_msgs.msg import JointState
from unilabos_msgs.action import SendCmd
from rclpy.action.server import ServerGoalHandle
@@ -11,9 +14,11 @@ from unilabos.ros.nodes.base_device_node import BaseROS2DeviceNode
from tf_transformations import quaternion_from_euler
from tf2_ros import TransformBroadcaster, Buffer, TransformListener
+from rclpy.node import Node
+import re
class LiquidHandlerJointPublisher(BaseROS2DeviceNode):
- def __init__(self,device_id:str, joint_config:dict, lh_id:str,resource_tracker, rate=50):
+ def __init__(self,resources_config:list, resource_tracker, rate=50, device_id:str = "lh_joint_publisher"):
super().__init__(
driver_instance=self,
device_id=device_id,
@@ -23,60 +28,118 @@ class LiquidHandlerJointPublisher(BaseROS2DeviceNode):
print_publish=False,
resource_tracker=resource_tracker,
)
-
- # joint_config_dict = {
- # "joint_names":[
- # "first_joint",
- # "second_joint",
- # "third_joint",
- # "fourth_joint"
- # ],
- # "y":{
- # "first_joint":{
- # "factor":-1,
- # "offset":0.0
- # }
- # },
- # "x":{
- # "second_joint":{
- # "factor":-1,
- # "offset":0.0
- # }
- # },
- # "z":{
- # "third_joint":{
- # "factor":1,
- # "offset":0.0
- # },
- # "fourth_joint":{
- # "factor":1,
- # "offset":0.0
- # }
- # }
- # }
-
+
+ # 初始化参数
self.j_msg = JointState()
- self.lh_id = lh_id
- # self.j_msg.name = joint_names
- self.joint_config = joint_config
- self.j_msg.position = [0.0 for i in range(len(joint_config['joint_names']))]
- self.j_msg.name = [f"{self.lh_id}_{x}" for x in joint_config['joint_names']]
- # self.joint_config = joint_config_dict
- # self.j_msg.position = [0.0 for i in range(len(joint_config_dict['joint_names']))]
- # self.j_msg.name = [f"{self.lh_id}_{x}" for x in joint_config_dict['joint_names']]
+ joint_config = json.load(open(f"{Path(__file__).parent.absolute()}/lh_joint_config.json", encoding="utf-8"))
+ self.resources_config = {x['id']:x for x in resources_config}
self.rate = rate
self.tf_buffer = Buffer()
self.tf_listener = TransformListener(self.tf_buffer, self)
self.j_pub = self.create_publisher(JointState,'/joint_states',10)
- self.create_timer(0.02,self.lh_joint_pub_callback)
+ self.create_timer(1,self.lh_joint_pub_callback)
+
+
+ self.resource_action = None
+
+ while self.resource_action is None:
+ self.resource_action = self.check_tf_update_actions()
+ time.sleep(1)
+
+ self.resource_action_client = ActionClient(self, SendCmd, self.resource_action)
+ while not self.resource_action_client.wait_for_server(timeout_sec=1.0):
+ self.get_logger().info('等待 TfUpdate 服务器...')
+
+ self.deck_list = []
+ self.lh_devices = {}
+ # 初始化设备ID与config信息
+ for resource in resources_config:
+ if resource['class'] == 'liquid_handler':
+ deck_id = resource['config']['data']['children'][0]['_resource_child_name']
+ deck_class = resource['config']['data']['children'][0]['_resource_type'].split(':')[-1]
+ key = f'{deck_id}'
+ # key = f'{resource["id"]}_{deck_id}'
+ self.lh_devices[key] = {
+ 'joint_msg':JointState(
+ name=[f'{key}_{x}' for x in joint_config[deck_class]['joint_names']],
+ position=[0.0 for _ in joint_config[deck_class]['joint_names']]
+ ),
+ 'joint_config':joint_config[deck_class]
+ }
+ self.deck_list.append(deck_id)
+
+ print('='*20)
+ print(self.lh_devices)
+ print('='*20)
self.j_action = ActionServer(
self,
SendCmd,
- "joint",
+ "hl_joint_action",
self.lh_joint_action_callback,
result_timeout=5000
)
+
+ def check_tf_update_actions(self):
+ topics = self.get_topic_names_and_types()
+
+
+ for topic_item in topics:
+
+ topic_name, topic_types = topic_item
+
+ if 'action_msgs/msg/GoalStatusArray' in topic_types:
+ # 删除 /_action/status 部分
+
+ base_name = topic_name.replace('/_action/status', '')
+ # 检查最后一个部分是否为 tf_update
+ parts = base_name.split('/')
+ if parts and parts[-1] == 'tf_update':
+ return base_name
+
+ return None
+
+
+ def find_resource_parent(self, resource_id:str):
+ # 遍历父辈,找到父辈的父辈,直到找到设备ID
+ parent_id = self.resources_config[resource_id]['parent']
+ try:
+ if parent_id in self.deck_list:
+ p_ = self.resources_config[parent_id]['parent']
+ str_ = f'{parent_id}'
+ return str(str_)
+ else:
+ return self.find_resource_parent(parent_id)
+ except Exception as e:
+ return None
+
+
+ def send_resource_action(self, resource_id_list:list[str], link_name:str):
+ goal_msg = SendCmd.Goal()
+ str_dict = {}
+ for resource in resource_id_list:
+ str_dict[resource] = link_name
+
+ goal_msg.command = json.dumps(str_dict)
+ self.resource_action_client.send_goal(goal_msg)
+
+ def resource_move(self, resource_id:str, link_name:str, channels:list[int]):
+ resource = resource_id.rsplit("_",1)
+
+ channel_list = ['A','B','C','D','E','F','G','H']
+
+ resource_list = []
+ match = re.match(r'([a-zA-Z_]+)(\d+)', resource[1])
+ if match:
+ number = match.group(2)
+ for channel in channels:
+ resource_list.append(f"{resource[0]}_{channel_list[channel]}{number}")
+
+ if len(resource_list) > 0:
+ self.send_resource_action(resource_list, link_name)
+
+
+
def lh_joint_action_callback(self,goal_handle: ServerGoalHandle):
"""Move a single joint
@@ -101,12 +164,13 @@ class LiquidHandlerJointPublisher(BaseROS2DeviceNode):
goal_handle.succeed()
except Exception as e:
- print(e)
+ print(f'Liquid handler action error: \n{e}')
goal_handle.abort()
result.success = False
-
+
return result
def inverse_kinematics(self, x, y, z,
+ parent_id,
x_joint:dict,
y_joint:dict,
z_joint:dict ):
@@ -117,77 +181,102 @@ class LiquidHandlerJointPublisher(BaseROS2DeviceNode):
x (float): x坐标
y (float): y坐标
z (float): z坐标
- x_joint (dict): x轴关节配置,包含plus和offset
- y_joint (dict): y轴关节配置,包含plus和offset
- z_joint (dict): z轴关节配置,包含plus和offset
+ x_joint (dict): x轴关节配置,包含factor和offset
+ y_joint (dict): y轴关节配置,包含factor和offset
+ z_joint (dict): z轴关节配置,包含factor和offset
Returns:
dict: 关节名称和对应位置的字典
"""
- joint_positions = copy.deepcopy(self.j_msg.position)
+ joint_positions = copy.deepcopy(self.lh_devices[parent_id]['joint_msg'].position)
+ z_index = 0
# 处理x轴关节
for joint_name, config in x_joint.items():
- index = self.j_msg.name.index(f"{self.lh_id}_{joint_name}")
+ index = self.lh_devices[parent_id]['joint_msg'].name.index(f"{parent_id}_{joint_name}")
joint_positions[index] = x * config["factor"] + config["offset"]
# 处理y轴关节
for joint_name, config in y_joint.items():
- index = self.j_msg.name.index(f"{self.lh_id}_{joint_name}")
+ index = self.lh_devices[parent_id]['joint_msg'].name.index(f"{parent_id}_{joint_name}")
joint_positions[index] = y * config["factor"] + config["offset"]
# 处理z轴关节
for joint_name, config in z_joint.items():
- index = self.j_msg.name.index(f"{self.lh_id}_{joint_name}")
+ index = self.lh_devices[parent_id]['joint_msg'].name.index(f"{parent_id}_{joint_name}")
joint_positions[index] = z * config["factor"] + config["offset"]
-
-
- return joint_positions
+ z_index = index
+
+ return joint_positions ,z_index
- def move_joints(self, resource_name, link_name, speed, x_joint=None, y_joint=None, z_joint=None):
+ def move_joints(self, resource_names, x, y, z, option, speed = 0.1 ,x_joint=None, y_joint=None, z_joint=None):
+ if isinstance(resource_names, list):
+ resource_name_ = resource_names[0]
+ else:
+ resource_name_ = resource_names
- transform = self.tf_buffer.lookup_transform(
- link_name,
- resource_name,
- rclpy.time.Time()
- )
- x,y,z = transform.transform.translation.x, transform.transform.translation.y, transform.transform.translation.z
+ parent_id = self.find_resource_parent(resource_name_)
+
+
+ print('!'*20)
+ print(parent_id)
+ print('!'*20)
if x_joint is None:
- x_joint_config = next(iter(self.joint_config['x'].items()))
- elif x_joint in self.joint_config['x']:
- x_joint_config = self.joint_config['x'][x_joint]
+ xa,xb = next(iter(self.lh_devices[parent_id]['joint_config']['x'].items()))
+ x_joint_config = {xa:xb}
+ elif x_joint in self.lh_devices[parent_id]['joint_config']['x']:
+ x_joint_config = self.lh_devices[parent_id]['joint_config']['x'][x_joint]
else:
raise ValueError(f"x_joint {x_joint} not in joint_config['x']")
if y_joint is None:
- y_joint_config = next(iter(self.joint_config['y'].items()))
- elif y_joint in self.joint_config['y']:
- y_joint_config = self.joint_config['y'][y_joint]
+ ya,yb = next(iter(self.lh_devices[parent_id]['joint_config']['y'].items()))
+ y_joint_config = {ya:yb}
+ elif y_joint in self.lh_devices[parent_id]['joint_config']['y']:
+ y_joint_config = self.lh_devices[parent_id]['joint_config']['y'][y_joint]
else:
raise ValueError(f"y_joint {y_joint} not in joint_config['y']")
if z_joint is None:
- z_joint_config = next(iter(self.joint_config['z'].items()))
- elif z_joint in self.joint_config['z']:
- z_joint_config = self.joint_config['z'][z_joint]
+ za, zb = next(iter(self.lh_devices[parent_id]['joint_config']['z'].items()))
+ z_joint_config = {za :zb}
+ elif z_joint in self.lh_devices[parent_id]['joint_config']['z']:
+ z_joint_config = self.lh_devices[parent_id]['joint_config']['z'][z_joint]
else:
raise ValueError(f"z_joint {z_joint} not in joint_config['z']")
- joint_positions_target = self.inverse_kinematics(x,y,z,x_joint_config,y_joint_config,z_joint_config)
+ joint_positions_target, z_index = self.inverse_kinematics(x,y,z,parent_id,x_joint_config,y_joint_config,z_joint_config)
+ joint_positions_target_zero = copy.deepcopy(joint_positions_target)
+ joint_positions_target_zero[z_index] = 0
+
+ self.move_to(joint_positions_target_zero, speed, parent_id)
+ self.move_to(joint_positions_target, speed, parent_id)
+ time.sleep(1)
+ if option == "pick":
+ link_name = self.lh_devices[parent_id]['joint_config']['link_names'][z_index]
+ link_name = f'{parent_id}_{link_name}'
+ self.resource_move(resource_name_, link_name, [0,1,2,3,4,5,6,7])
+ elif option == "drop_trash":
+ self.resource_move(resource_name_, "__trash", [0,1,2,3,4,5,6,7])
+ elif option == "drop":
+ self.resource_move(resource_name_, "world", [0,1,2,3,4,5,6,7])
+ self.move_to(joint_positions_target_zero, speed, parent_id)
+
+
+ def move_to(self, joint_positions ,speed, parent_id):
loop_flag = 0
-
- while loop_flag < len(self.joint_config['joint_names']):
+ while loop_flag < len(joint_positions):
loop_flag = 0
- for i in range(len(self.joint_config['joint_names'])):
- distance = joint_positions_target[i] - self.j_msg.position[i]
+ for i in range(len(joint_positions)):
+ distance = joint_positions[i] - self.lh_devices[parent_id]['joint_msg'].position[i]
if distance == 0:
loop_flag += 1
continue
minus_flag = distance/abs(distance)
if abs(distance) > speed/self.rate:
- self.j_msg.position[i] += minus_flag * speed/self.rate
+ self.lh_devices[parent_id]['joint_msg'].position[i] += minus_flag * speed/self.rate
else :
- self.j_msg.position[i] = joint_positions_target[i]
+ self.lh_devices[parent_id]['joint_msg'].position[i] = joint_positions[i]
loop_flag += 1
@@ -195,10 +284,103 @@ class LiquidHandlerJointPublisher(BaseROS2DeviceNode):
self.lh_joint_pub_callback()
time.sleep(1/self.rate)
-
def lh_joint_pub_callback(self):
- self.j_msg.header.stamp = self.get_clock().now().to_msg()
- self.j_pub.publish(self.j_msg)
+ for id, config in self.lh_devices.items():
+ config['joint_msg'].header.stamp = self.get_clock().now().to_msg()
+ self.j_pub.publish(config['joint_msg'])
+
+
+
+
+class JointStatePublisher(Node):
+ def __init__(self):
+ super().__init__('joint_state_publisher')
+
+ self.lh_action = None
+
+ while self.lh_action is None:
+ self.lh_action = self.check_hl_joint_actions()
+ time.sleep(1)
+
+ self.lh_action_client = ActionClient(self, SendCmd, self.lh_action)
+ while not self.lh_action_client.wait_for_server(timeout_sec=1.0):
+ self.get_logger().info('等待 TfUpdate 服务器...')
+
+
+
+ def check_hl_joint_actions(self):
+ topics = self.get_topic_names_and_types()
+
+
+ for topic_item in topics:
+
+ topic_name, topic_types = topic_item
+
+ if 'action_msgs/msg/GoalStatusArray' in topic_types:
+ # 删除 /_action/status 部分
+
+ base_name = topic_name.replace('/_action/status', '')
+ # 检查最后一个部分是否为 tf_update
+ parts = base_name.split('/')
+ if parts and parts[-1] == 'hl_joint_action':
+ return base_name
+
+ return None
+
+ def send_resource_action(self, resource_name, x,y,z,option, speed = 0.1,x_joint=None, y_joint=None, z_joint=None):
+ goal_msg = SendCmd.Goal()
+ str_dict = {
+ 'resource_names':resource_name,
+ 'x':x,
+ 'y':y,
+ 'z':z,
+ 'option':option,
+ 'speed':speed,
+ 'x_joint':x_joint,
+ 'y_joint':y_joint,
+ 'z_joint':z_joint
+ }
+
+
+ goal_msg.command = json.dumps(str_dict)
+
+ if not self.lh_action_client.wait_for_server(timeout_sec=5.0):
+ self.get_logger().error('Action server not available')
+ return None
+
+ try:
+ # 创建新的executor
+ executor = rclpy.executors.MultiThreadedExecutor()
+ executor.add_node(self)
+
+ # 发送目标
+ future = self.lh_action_client.send_goal_async(goal_msg)
+
+ # 使用executor等待结果
+ while not future.done():
+ executor.spin_once(timeout_sec=0.1)
+
+ handle = future.result()
+
+ if not handle.accepted:
+ self.get_logger().error('Goal was rejected')
+ return None
+
+ # 等待最终结果
+ result_future = handle.get_result_async()
+ while not result_future.done():
+ executor.spin_once(timeout_sec=0.1)
+
+ result = result_future.result()
+ return result
+
+ except Exception as e:
+ self.get_logger().error(f'Error during action execution: {str(e)}')
+ return None
+ finally:
+ # 清理executor
+ executor.remove_node(self)
+
def main():
diff --git a/unilabos/devices/ros_dev/moveit2.py b/unilabos/devices/ros_dev/moveit2.py
new file mode 100644
index 0000000..80bea9d
--- /dev/null
+++ b/unilabos/devices/ros_dev/moveit2.py
@@ -0,0 +1,2442 @@
+import copy
+import threading
+from enum import Enum
+from typing import Any, List, Optional, Tuple, Union
+
+import numpy as np
+from action_msgs.msg import GoalStatus
+from geometry_msgs.msg import Point, Pose, PoseStamped, Quaternion
+from moveit_msgs.action import ExecuteTrajectory, MoveGroup
+from moveit_msgs.msg import (
+ AllowedCollisionEntry,
+ AttachedCollisionObject,
+ CollisionObject,
+ Constraints,
+ JointConstraint,
+ MoveItErrorCodes,
+ OrientationConstraint,
+ PlanningScene,
+ PositionConstraint,
+)
+from moveit_msgs.srv import (
+ ApplyPlanningScene,
+ GetCartesianPath,
+ GetMotionPlan,
+ GetPlanningScene,
+ GetPositionFK,
+ GetPositionIK,
+)
+from rclpy.action import ActionClient
+from rclpy.callback_groups import CallbackGroup
+from rclpy.node import Node
+from rclpy.qos import (
+ QoSDurabilityPolicy,
+ QoSHistoryPolicy,
+ QoSProfile,
+ QoSReliabilityPolicy,
+)
+from rclpy.task import Future
+from sensor_msgs.msg import JointState
+from shape_msgs.msg import Mesh, MeshTriangle, SolidPrimitive
+from std_msgs.msg import Header, String
+from trajectory_msgs.msg import JointTrajectory, JointTrajectoryPoint
+
+
+class MoveIt2State(Enum):
+ """
+ An enum the represents the current execution state of the MoveIt2 interface.
+ - IDLE: No motion is being requested or executed
+ - REQUESTING: Execution has been requested, but the request has not yet been
+ accepted.
+ - EXECUTING: Execution has been requested and accepted, and has not yet been
+ completed.
+ """
+
+ IDLE = 0
+ REQUESTING = 1
+ EXECUTING = 2
+
+
+class MoveIt2:
+ """
+ Python interface for MoveIt 2 that enables planning and execution of trajectories.
+ For execution, this interface requires that robot utilises JointTrajectoryController.
+ """
+
+ def __init__(
+ self,
+ node: Node,
+ joint_names: List[str],
+ base_link_name: str,
+ end_effector_name: str,
+ group_name: str = "arm",
+ execute_via_moveit: bool = False,
+ ignore_new_calls_while_executing: bool = False,
+ callback_group: Optional[CallbackGroup] = None,
+ follow_joint_trajectory_action_name: str = "DEPRECATED",
+ use_move_group_action: bool = False,
+ ):
+ """
+ Construct an instance of `MoveIt2` interface.
+ - `node` - ROS 2 node that this interface is attached to
+ - `joint_names` - List of joint names of the robot (can be extracted from URDF)
+ - `base_link_name` - Name of the robot base link
+ - `end_effector_name` - Name of the robot end effector
+ - `group_name` - Name of the planning group for robot arm
+ - [DEPRECATED] `execute_via_moveit` - Flag that enables execution via MoveGroup action (MoveIt 2)
+ FollowJointTrajectory action (controller) is employed otherwise
+ together with a separate planning service client
+ - `ignore_new_calls_while_executing` - Flag to ignore requests to execute new trajectories
+ while previous is still being executed
+ - `callback_group` - Optional callback group to use for ROS 2 communication (topics/services/actions)
+ - [DEPRECATED] `follow_joint_trajectory_action_name` - Name of the action server for the controller
+ - `use_move_group_action` - Flag that enables execution via MoveGroup action (MoveIt 2)
+ ExecuteTrajectory action is employed otherwise
+ together with a separate planning service client
+ """
+
+ self._node = node
+ self._callback_group = callback_group
+
+ # Check for deprecated parameters
+ if execute_via_moveit:
+ self._node.get_logger().warn(
+ "Parameter `execute_via_moveit` is deprecated. Please use `use_move_group_action` instead."
+ )
+ use_move_group_action = True
+ if follow_joint_trajectory_action_name != "DEPRECATED":
+ self._node.get_logger().warn(
+ "Parameter `follow_joint_trajectory_action_name` is deprecated. `MoveIt2` uses the `execute_trajectory` action instead."
+ )
+
+ # Create subscriber for current joint states
+ self._node.create_subscription(
+ msg_type=JointState,
+ topic="/joint_states",
+ callback=self.__joint_state_callback,
+ qos_profile=QoSProfile(
+ durability=QoSDurabilityPolicy.VOLATILE,
+ reliability=QoSReliabilityPolicy.BEST_EFFORT,
+ history=QoSHistoryPolicy.KEEP_LAST,
+ depth=1,
+ ),
+ callback_group=self._callback_group,
+ )
+
+ # Create action client for move action
+ self.__move_action_client = ActionClient(
+ node=self._node,
+ action_type=MoveGroup,
+ action_name="/move_action",
+ goal_service_qos_profile=QoSProfile(
+ durability=QoSDurabilityPolicy.VOLATILE,
+ reliability=QoSReliabilityPolicy.RELIABLE,
+ history=QoSHistoryPolicy.KEEP_LAST,
+ depth=1,
+ ),
+ result_service_qos_profile=QoSProfile(
+ durability=QoSDurabilityPolicy.VOLATILE,
+ reliability=QoSReliabilityPolicy.RELIABLE,
+ history=QoSHistoryPolicy.KEEP_LAST,
+ depth=5,
+ ),
+ cancel_service_qos_profile=QoSProfile(
+ durability=QoSDurabilityPolicy.VOLATILE,
+ reliability=QoSReliabilityPolicy.RELIABLE,
+ history=QoSHistoryPolicy.KEEP_LAST,
+ depth=5,
+ ),
+ feedback_sub_qos_profile=QoSProfile(
+ durability=QoSDurabilityPolicy.VOLATILE,
+ reliability=QoSReliabilityPolicy.BEST_EFFORT,
+ history=QoSHistoryPolicy.KEEP_LAST,
+ depth=1,
+ ),
+ status_sub_qos_profile=QoSProfile(
+ durability=QoSDurabilityPolicy.VOLATILE,
+ reliability=QoSReliabilityPolicy.BEST_EFFORT,
+ history=QoSHistoryPolicy.KEEP_LAST,
+ depth=1,
+ ),
+ callback_group=self._callback_group,
+ )
+
+ # Also create a separate service client for planning
+ self._plan_kinematic_path_service = self._node.create_client(
+ srv_type=GetMotionPlan,
+ srv_name="/plan_kinematic_path",
+ qos_profile=QoSProfile(
+ durability=QoSDurabilityPolicy.VOLATILE,
+ reliability=QoSReliabilityPolicy.RELIABLE,
+ history=QoSHistoryPolicy.KEEP_LAST,
+ depth=1,
+ ),
+ callback_group=callback_group,
+ )
+ self.__kinematic_path_request = GetMotionPlan.Request()
+
+ # Create a separate service client for Cartesian planning
+ self._plan_cartesian_path_service = self._node.create_client(
+ srv_type=GetCartesianPath,
+ srv_name="/compute_cartesian_path",
+ qos_profile=QoSProfile(
+ durability=QoSDurabilityPolicy.VOLATILE,
+ reliability=QoSReliabilityPolicy.RELIABLE,
+ history=QoSHistoryPolicy.KEEP_LAST,
+ depth=1,
+ ),
+ callback_group=callback_group,
+ )
+ self.__cartesian_path_request = GetCartesianPath.Request()
+
+ # Create action client for trajectory execution
+ self._execute_trajectory_action_client = ActionClient(
+ node=self._node,
+ action_type=ExecuteTrajectory,
+ action_name="/execute_trajectory",
+ goal_service_qos_profile=QoSProfile(
+ durability=QoSDurabilityPolicy.VOLATILE,
+ reliability=QoSReliabilityPolicy.RELIABLE,
+ history=QoSHistoryPolicy.KEEP_LAST,
+ depth=1,
+ ),
+ result_service_qos_profile=QoSProfile(
+ durability=QoSDurabilityPolicy.VOLATILE,
+ reliability=QoSReliabilityPolicy.RELIABLE,
+ history=QoSHistoryPolicy.KEEP_LAST,
+ depth=5,
+ ),
+ cancel_service_qos_profile=QoSProfile(
+ durability=QoSDurabilityPolicy.VOLATILE,
+ reliability=QoSReliabilityPolicy.RELIABLE,
+ history=QoSHistoryPolicy.KEEP_LAST,
+ depth=5,
+ ),
+ feedback_sub_qos_profile=QoSProfile(
+ durability=QoSDurabilityPolicy.VOLATILE,
+ reliability=QoSReliabilityPolicy.BEST_EFFORT,
+ history=QoSHistoryPolicy.KEEP_LAST,
+ depth=1,
+ ),
+ status_sub_qos_profile=QoSProfile(
+ durability=QoSDurabilityPolicy.VOLATILE,
+ reliability=QoSReliabilityPolicy.BEST_EFFORT,
+ history=QoSHistoryPolicy.KEEP_LAST,
+ depth=1,
+ ),
+ callback_group=self._callback_group,
+ )
+
+ # Create a service for getting the planning scene
+ self._get_planning_scene_service = self._node.create_client(
+ srv_type=GetPlanningScene,
+ srv_name="/get_planning_scene",
+ qos_profile=QoSProfile(
+ durability=QoSDurabilityPolicy.VOLATILE,
+ reliability=QoSReliabilityPolicy.RELIABLE,
+ history=QoSHistoryPolicy.KEEP_LAST,
+ depth=1,
+ ),
+ callback_group=callback_group,
+ )
+ self.__planning_scene = None
+ self.__old_planning_scene = None
+ self.__old_allowed_collision_matrix = None
+
+ # Create a service for applying the planning scene
+ self._apply_planning_scene_service = self._node.create_client(
+ srv_type=ApplyPlanningScene,
+ srv_name="/apply_planning_scene",
+ qos_profile=QoSProfile(
+ durability=QoSDurabilityPolicy.VOLATILE,
+ reliability=QoSReliabilityPolicy.RELIABLE,
+ history=QoSHistoryPolicy.KEEP_LAST,
+ depth=1,
+ ),
+ callback_group=callback_group,
+ )
+
+ self.__collision_object_publisher = self._node.create_publisher(
+ CollisionObject, "/collision_object", 10
+ )
+ self.__attached_collision_object_publisher = self._node.create_publisher(
+ AttachedCollisionObject, "/attached_collision_object", 10
+ )
+
+ self.__cancellation_pub = self._node.create_publisher(
+ String, "/trajectory_execution_event", 1
+ )
+
+ self.__joint_state_mutex = threading.Lock()
+ self.__joint_state = None
+ self.__new_joint_state_available = False
+ self.__move_action_goal = self.__init_move_action_goal(
+ frame_id=base_link_name,
+ group_name=group_name,
+ end_effector=end_effector_name,
+ )
+
+ # Flag to determine whether to execute trajectories via Move Group Action, or rather by calling
+ # the separate ExecuteTrajectory action
+ # Applies to `move_to_pose()` and `move_to_configuration()`
+ self.__use_move_group_action = use_move_group_action
+
+ # Flag that determines whether a new goal can be sent while the previous one is being executed
+ self.__ignore_new_calls_while_executing = ignore_new_calls_while_executing
+
+ # Store additional variables for later use
+ self.__joint_names = joint_names
+ self.__base_link_name = base_link_name
+ self.__end_effector_name = end_effector_name
+ self.__group_name = group_name
+
+ # Internal states that monitor the current motion requests and execution
+ self.__is_motion_requested = False
+ self.__is_executing = False
+ self.motion_suceeded = False
+ self.__execution_goal_handle = None
+ self.__last_error_code = None
+ self.__wait_until_executed_rate = self._node.create_rate(1000.0)
+ self.__execution_mutex = threading.Lock()
+
+ # Event that enables waiting until async future is done
+ self.__future_done_event = threading.Event()
+
+ #### Execution Polling Functions
+ def query_state(self) -> MoveIt2State:
+ with self.__execution_mutex:
+ if self.__is_motion_requested:
+ return MoveIt2State.REQUESTING
+ elif self.__is_executing:
+ return MoveIt2State.EXECUTING
+ else:
+ return MoveIt2State.IDLE
+
+ def cancel_execution(self):
+ if self.query_state() != MoveIt2State.EXECUTING:
+ self._node.get_logger().warn("Attempted to cancel without active goal.")
+ return None
+
+ cancel_string = String()
+ cancel_string.data = "stop"
+ self.__cancellation_pub.publish(cancel_string)
+
+ def get_execution_future(self) -> Optional[Future]:
+ if self.query_state() != MoveIt2State.EXECUTING:
+ self._node.get_logger().warn("Need active goal for future.")
+ return None
+
+ return self.__execution_goal_handle.get_result_async()
+
+ def get_last_execution_error_code(self) -> Optional[MoveItErrorCodes]:
+ return self.__last_error_code
+
+ ####
+
+ def move_to_pose(
+ self,
+ pose: Optional[Union[PoseStamped, Pose]] = None,
+ position: Optional[Union[Point, Tuple[float, float, float]]] = None,
+ quat_xyzw: Optional[
+ Union[Quaternion, Tuple[float, float, float, float]]
+ ] = None,
+ target_link: Optional[str] = None,
+ frame_id: Optional[str] = None,
+ tolerance_position: float = 0.001,
+ tolerance_orientation: float = 0.001,
+ weight_position: float = 1.0,
+ cartesian: bool = True,
+ weight_orientation: float = 1.0,
+ cartesian_max_step: float = 0.0025,
+ cartesian_fraction_threshold: float = 0.0,
+ ):
+ """
+ Plan and execute motion based on previously set goals. Optional arguments can be
+ passed in to internally use `set_pose_goal()` to define a goal during the call.
+ """
+
+ if isinstance(pose, PoseStamped):
+ pose_stamped = pose
+ elif isinstance(pose, Pose):
+ pose_stamped = PoseStamped(
+ header=Header(
+ stamp=self._node.get_clock().now().to_msg(),
+ frame_id=(
+ frame_id if frame_id is not None else self.__base_link_name
+ ),
+ ),
+ pose=pose,
+ )
+ else:
+ if not isinstance(position, Point):
+ position = Point(
+ x=float(position[0]), y=float(position[1]), z=float(position[2])
+ )
+ if not isinstance(quat_xyzw, Quaternion):
+ quat_xyzw = Quaternion(
+ x=float(quat_xyzw[0]),
+ y=float(quat_xyzw[1]),
+ z=float(quat_xyzw[2]),
+ w=float(quat_xyzw[3]),
+ )
+ pose_stamped = PoseStamped(
+ header=Header(
+ stamp=self._node.get_clock().now().to_msg(),
+ frame_id=(
+ frame_id if frame_id is not None else self.__base_link_name
+ ),
+ ),
+ pose=Pose(position=position, orientation=quat_xyzw),
+ )
+
+ if self.__use_move_group_action and not cartesian:
+ if self.__ignore_new_calls_while_executing and (
+ self.__is_motion_requested or self.__is_executing
+ ):
+ self._node.get_logger().warn(
+ "Controller is already following a trajectory. Skipping motion."
+ )
+ return
+
+ # Set goal
+ self.set_pose_goal(
+ position=pose_stamped.pose.position,
+ quat_xyzw=pose_stamped.pose.orientation,
+ frame_id=pose_stamped.header.frame_id,
+ target_link=target_link,
+ tolerance_position=tolerance_position,
+ tolerance_orientation=tolerance_orientation,
+ weight_position=weight_position,
+ weight_orientation=weight_orientation,
+ )
+ # Define starting state as the current state
+ if self.joint_state is not None:
+ self.__move_action_goal.request.start_state.joint_state = (
+ self.joint_state
+ )
+ # Send to goal to the server (async) - both planning and execution
+ self._send_goal_async_move_action()
+ # Clear all previous goal constrains
+ self.clear_goal_constraints()
+ self.clear_path_constraints()
+
+ else:
+ # Plan via MoveIt 2 and then execute directly with the controller
+ self.execute(
+ self.plan(
+ position=pose_stamped.pose.position,
+ quat_xyzw=pose_stamped.pose.orientation,
+ frame_id=pose_stamped.header.frame_id,
+ target_link=target_link,
+ tolerance_position=tolerance_position,
+ tolerance_orientation=tolerance_orientation,
+ weight_position=weight_position,
+ weight_orientation=weight_orientation,
+ cartesian=cartesian,
+ max_step=cartesian_max_step,
+ cartesian_fraction_threshold=cartesian_fraction_threshold,
+ )
+ )
+
+ def move_to_configuration(
+ self,
+ joint_positions: List[float],
+ joint_names: Optional[List[str]] = None,
+ tolerance: float = 0.001,
+ weight: float = 1.0,
+ cartesian: bool = False,
+ ):
+ """
+ Plan and execute motion based on previously set goals. Optional arguments can be
+ passed in to internally use `set_joint_goal()` to define a goal during the call.
+ """
+
+ if self.__use_move_group_action:
+ if self.__ignore_new_calls_while_executing and (
+ self.__is_motion_requested or self.__is_executing
+ ):
+ self._node.get_logger().warn(
+ "Controller is already following a trajectory. Skipping motion."
+ )
+ return
+
+ # Set goal
+ self.set_joint_goal(
+ joint_positions=joint_positions,
+ joint_names=joint_names,
+ tolerance=tolerance,
+ weight=weight,
+ )
+ # Define starting state as the current state
+ if self.joint_state is not None:
+ self.__move_action_goal.request.start_state.joint_state = (
+ self.joint_state
+ )
+ # Send to goal to the server (async) - both planning and execution
+ self._send_goal_async_move_action()
+ # Clear all previous goal constrains
+ self.clear_goal_constraints()
+ self.clear_path_constraints()
+
+ else:
+ # Plan via MoveIt 2 and then execute directly with the controller
+ self.execute(
+ self.plan(
+ joint_positions=joint_positions,
+ joint_names=joint_names,
+ tolerance_joint_position=tolerance,
+ weight_joint_position=weight,
+ cartesian=cartesian,
+ )
+ )
+
+ def plan(
+ self,
+ pose: Optional[Union[PoseStamped, Pose]] = None,
+ position: Optional[Union[Point, Tuple[float, float, float]]] = None,
+ quat_xyzw: Optional[
+ Union[Quaternion, Tuple[float, float, float, float]]
+ ] = None,
+ joint_positions: Optional[List[float]] = None,
+ joint_names: Optional[List[str]] = None,
+ frame_id: Optional[str] = None,
+ target_link: Optional[str] = None,
+ tolerance_position: float = 0.001,
+ tolerance_orientation: Union[float, Tuple[float, float, float]] = 0.001,
+ tolerance_joint_position: float = 0.001,
+ weight_position: float = 1.0,
+ weight_orientation: float = 1.0,
+ weight_joint_position: float = 1.0,
+ start_joint_state: Optional[Union[JointState, List[float]]] = None,
+ cartesian: bool = False,
+ max_step: float = 0.0025,
+ cartesian_fraction_threshold: float = 0.0,
+ ) -> Optional[JointTrajectory]:
+ """
+ Call plan_async and wait on future
+ """
+ future = self.plan_async(
+ **{
+ key: value
+ for key, value in locals().items()
+ if key not in ["self", "cartesian_fraction_threshold"]
+ }
+ )
+
+ if future is None:
+ return None
+
+ # 100ms sleep
+ rate = self._node.create_rate(10)
+ while not future.done():
+ rate.sleep()
+
+ return self.get_trajectory(
+ future,
+ cartesian=cartesian,
+ cartesian_fraction_threshold=cartesian_fraction_threshold,
+ )
+
+ def plan_async(
+ self,
+ pose: Optional[Union[PoseStamped, Pose]] = None,
+ position: Optional[Union[Point, Tuple[float, float, float]]] = None,
+ quat_xyzw: Optional[
+ Union[Quaternion, Tuple[float, float, float, float]]
+ ] = None,
+ joint_positions: Optional[List[float]] = None,
+ joint_names: Optional[List[str]] = None,
+ frame_id: Optional[str] = None,
+ target_link: Optional[str] = None,
+ tolerance_position: float = 0.001,
+ tolerance_orientation: Union[float, Tuple[float, float, float]] = 0.001,
+ tolerance_joint_position: float = 0.001,
+ weight_position: float = 1.0,
+ weight_orientation: float = 1.0,
+ weight_joint_position: float = 1.0,
+ start_joint_state: Optional[Union[JointState, List[float]]] = None,
+ cartesian: bool = False,
+ max_step: float = 0.0025,
+ ) -> Optional[Future]:
+ """
+ Plan motion based on previously set goals. Optional arguments can be passed in to
+ internally use `set_position_goal()`, `set_orientation_goal()` or `set_joint_goal()`
+ to define a goal during the call. If no trajectory is found within the timeout
+ duration, `None` is returned. To plan from the different position than the current
+ one, optional argument `start_` can be defined.
+ """
+
+ pose_stamped = None
+ if pose is not None:
+ if isinstance(pose, PoseStamped):
+ pose_stamped = pose
+ elif isinstance(pose, Pose):
+ pose_stamped = PoseStamped(
+ header=Header(
+ stamp=self._node.get_clock().now().to_msg(),
+ frame_id=(
+ frame_id if frame_id is not None else self.__base_link_name
+ ),
+ ),
+ pose=pose,
+ )
+
+ self.set_position_goal(
+ position=pose_stamped.pose.position,
+ frame_id=pose_stamped.header.frame_id,
+ target_link=target_link,
+ tolerance=tolerance_position,
+ weight=weight_position,
+ )
+ self.set_orientation_goal(
+ quat_xyzw=pose_stamped.pose.orientation,
+ frame_id=pose_stamped.header.frame_id,
+ target_link=target_link,
+ tolerance=tolerance_orientation,
+ weight=weight_orientation,
+ )
+ else:
+ if position is not None:
+ if not isinstance(position, Point):
+ position = Point(
+ x=float(position[0]), y=float(position[1]), z=float(position[2])
+ )
+
+ self.set_position_goal(
+ position=position,
+ frame_id=frame_id,
+ target_link=target_link,
+ tolerance=tolerance_position,
+ weight=weight_position,
+ )
+
+ if quat_xyzw is not None:
+ if not isinstance(quat_xyzw, Quaternion):
+ quat_xyzw = Quaternion(
+ x=float(quat_xyzw[0]),
+ y=float(quat_xyzw[1]),
+ z=float(quat_xyzw[2]),
+ w=float(quat_xyzw[3]),
+ )
+
+ self.set_orientation_goal(
+ quat_xyzw=quat_xyzw,
+ frame_id=frame_id,
+ target_link=target_link,
+ tolerance=tolerance_orientation,
+ weight=weight_orientation,
+ )
+
+ if joint_positions is not None:
+ self.set_joint_goal(
+ joint_positions=joint_positions,
+ joint_names=joint_names,
+ tolerance=tolerance_joint_position,
+ weight=weight_joint_position,
+ )
+
+ # Define starting state for the plan (default to the current state)
+ if start_joint_state is not None:
+ if isinstance(start_joint_state, JointState):
+ self.__move_action_goal.request.start_state.joint_state = (
+ start_joint_state
+ )
+ else:
+ self.__move_action_goal.request.start_state.joint_state = (
+ init_joint_state(
+ joint_names=self.__joint_names,
+ joint_positions=start_joint_state,
+ )
+ )
+ elif self.joint_state is not None:
+ self.__move_action_goal.request.start_state.joint_state = self.joint_state
+
+ # Plan trajectory asynchronously by service call
+ if cartesian:
+ future = self._plan_cartesian_path(
+ max_step=max_step,
+ frame_id=(
+ pose_stamped.header.frame_id
+ if pose_stamped is not None
+ else frame_id
+ ),
+ )
+ else:
+ # Use service
+ future = self._plan_kinematic_path()
+
+
+ # Clear all previous goal constrains
+ self.clear_goal_constraints()
+ self.clear_path_constraints()
+
+ return future
+
+ def get_trajectory(
+ self,
+ future: Future,
+ cartesian: bool = False,
+ cartesian_fraction_threshold: float = 0.0,
+ ) -> Optional[JointTrajectory]:
+ """
+ Takes in a future returned by plan_async and returns the trajectory if the future is done
+ and planning was successful, else None.
+
+ For cartesian plans, the plan is rejected if the fraction of the path that was completed is
+ less than `cartesian_fraction_threshold`.
+ """
+ if not future.done():
+ self._node.get_logger().warn(
+ "Cannot get trajectory because future is not done."
+ )
+ return None
+
+ res = future.result()
+
+ # Cartesian
+ if cartesian:
+ if MoveItErrorCodes.SUCCESS == res.error_code.val:
+ if res.fraction >= cartesian_fraction_threshold:
+ return res.solution.joint_trajectory
+ else:
+ self._node.get_logger().warn(
+ f"Planning failed! Cartesian planner completed {res.fraction} "
+ f"of the trajectory, less than the threshold {cartesian_fraction_threshold}."
+ )
+ return None
+ else:
+ self._node.get_logger().warn(
+ f"Planning failed! Error code: {res.error_code.val}."
+ )
+ return None
+
+ # Else Kinematic
+ res = res.motion_plan_response
+ if MoveItErrorCodes.SUCCESS == res.error_code.val:
+ return res.trajectory.joint_trajectory
+ else:
+ self._node.get_logger().warn(
+ f"Planning failed! Error code: {res.error_code.val}."
+ )
+ return None
+
+ def execute(self, joint_trajectory: JointTrajectory):
+ """
+ Execute joint_trajectory by communicating directly with the controller.
+ """
+
+ if self.__ignore_new_calls_while_executing and (
+ self.__is_motion_requested or self.__is_executing
+ ):
+ self._node.get_logger().warn(
+ "Controller is already following a trajectory. Skipping motion."
+ )
+ return
+
+ execute_trajectory_goal = init_execute_trajectory_goal(
+ joint_trajectory=joint_trajectory
+ )
+
+ if execute_trajectory_goal is None:
+ self._node.get_logger().warn(
+ "Cannot execute motion because the provided/planned trajectory is invalid."
+ )
+ return
+
+ self._send_goal_async_execute_trajectory(goal=execute_trajectory_goal)
+
+ def wait_until_executed(self) -> bool:
+ """
+ Wait until the previously requested motion is finalised through either a success or failure.
+ """
+
+ if not self.__is_motion_requested:
+ self._node.get_logger().warn(
+ "Cannot wait until motion is executed (no motion is in progress)."
+ )
+ return False
+
+ while self.__is_motion_requested or self.__is_executing:
+ self.__wait_until_executed_rate.sleep()
+
+ return self.motion_suceeded
+
+ def reset_controller(
+ self, joint_state: Union[JointState, List[float]], sync: bool = True
+ ):
+ """
+ Reset controller to a given `joint_state` by sending a dummy joint trajectory.
+ This is useful for simulated robots that allow instantaneous reset of joints.
+ """
+
+ if not isinstance(joint_state, JointState):
+ joint_state = init_joint_state(
+ joint_names=self.__joint_names,
+ joint_positions=joint_state,
+ )
+ joint_trajectory = init_dummy_joint_trajectory_from_state(joint_state)
+ execute_trajectory_goal = init_execute_trajectory_goal(
+ joint_trajectory=joint_trajectory
+ )
+
+ self._send_goal_async_execute_trajectory(
+ goal=execute_trajectory_goal,
+ wait_until_response=sync,
+ )
+
+ def set_pose_goal(
+ self,
+ pose: Optional[Union[PoseStamped, Pose]] = None,
+ position: Optional[Union[Point, Tuple[float, float, float]]] = None,
+ quat_xyzw: Optional[
+ Union[Quaternion, Tuple[float, float, float, float]]
+ ] = None,
+ frame_id: Optional[str] = None,
+ target_link: Optional[str] = None,
+ tolerance_position: float = 0.001,
+ tolerance_orientation: Union[float, Tuple[float, float, float]] = 0.001,
+ weight_position: float = 1.0,
+ weight_orientation: float = 1.0,
+ ):
+ """
+ This is direct combination of `set_position_goal()` and `set_orientation_goal()`.
+ """
+
+ if (pose is None) and (position is None or quat_xyzw is None):
+ raise ValueError(
+ "Either `pose` or `position` and `quat_xyzw` must be specified!"
+ )
+
+ if isinstance(pose, PoseStamped):
+ pose_stamped = pose
+ elif isinstance(pose, Pose):
+ pose_stamped = PoseStamped(
+ header=Header(
+ stamp=self._node.get_clock().now().to_msg(),
+ frame_id=(
+ frame_id if frame_id is not None else self.__base_link_name
+ ),
+ ),
+ pose=pose,
+ )
+ else:
+ if not isinstance(position, Point):
+ position = Point(
+ x=float(position[0]), y=float(position[1]), z=float(position[2])
+ )
+ if not isinstance(quat_xyzw, Quaternion):
+ quat_xyzw = Quaternion(
+ x=float(quat_xyzw[0]),
+ y=float(quat_xyzw[1]),
+ z=float(quat_xyzw[2]),
+ w=float(quat_xyzw[3]),
+ )
+ pose_stamped = PoseStamped(
+ header=Header(
+ stamp=self._node.get_clock().now().to_msg(),
+ frame_id=(
+ frame_id if frame_id is not None else self.__base_link_name
+ ),
+ ),
+ pose=Pose(position=position, orientation=quat_xyzw),
+ )
+
+ self.set_position_goal(
+ position=pose_stamped.pose.position,
+ frame_id=pose_stamped.header.frame_id,
+ target_link=target_link,
+ tolerance=tolerance_position,
+ weight=weight_position,
+ )
+ self.set_orientation_goal(
+ quat_xyzw=pose_stamped.pose.orientation,
+ frame_id=pose_stamped.header.frame_id,
+ target_link=target_link,
+ tolerance=tolerance_orientation,
+ weight=weight_orientation,
+ )
+
+ def create_position_constraint(
+ self,
+ position: Union[Point, Tuple[float, float, float]],
+ frame_id: Optional[str] = None,
+ target_link: Optional[str] = None,
+ tolerance: float = 0.001,
+ weight: float = 1.0,
+ ) -> PositionConstraint:
+ """
+ Create Cartesian position constraint of `target_link` with respect to `frame_id`.
+ - `frame_id` defaults to the base link
+ - `target_link` defaults to end effector
+ """
+
+ # Create new position constraint
+ constraint = PositionConstraint()
+
+ # Define reference frame and target link
+ constraint.header.frame_id = (
+ frame_id if frame_id is not None else self.__base_link_name
+ )
+ constraint.link_name = (
+ target_link if target_link is not None else self.__end_effector_name
+ )
+
+ # Define target position
+ constraint.constraint_region.primitive_poses.append(Pose())
+ if isinstance(position, Point):
+ constraint.constraint_region.primitive_poses[0].position = position
+ else:
+ constraint.constraint_region.primitive_poses[0].position.x = float(
+ position[0]
+ )
+ constraint.constraint_region.primitive_poses[0].position.y = float(
+ position[1]
+ )
+ constraint.constraint_region.primitive_poses[0].position.z = float(
+ position[2]
+ )
+
+ # Define goal region as a sphere with radius equal to the tolerance
+ constraint.constraint_region.primitives.append(SolidPrimitive())
+ constraint.constraint_region.primitives[0].type = 2 # Sphere
+ constraint.constraint_region.primitives[0].dimensions = [tolerance]
+
+ # Set weight of the constraint
+ constraint.weight = weight
+
+ return constraint
+
+ def set_position_goal(
+ self,
+ position: Union[Point, Tuple[float, float, float]],
+ frame_id: Optional[str] = None,
+ target_link: Optional[str] = None,
+ tolerance: float = 0.001,
+ weight: float = 1.0,
+ ):
+ """
+ Set Cartesian position goal of `target_link` with respect to `frame_id`.
+ - `frame_id` defaults to the base link
+ - `target_link` defaults to end effector
+ """
+
+ constraint = self.create_position_constraint(
+ position=position,
+ frame_id=frame_id,
+ target_link=target_link,
+ tolerance=tolerance,
+ weight=weight,
+ )
+
+ # Append to other constraints
+ self.__move_action_goal.request.goal_constraints[
+ -1
+ ].position_constraints.append(constraint)
+
+ def create_orientation_constraint(
+ self,
+ quat_xyzw: Union[Quaternion, Tuple[float, float, float, float]],
+ frame_id: Optional[str] = None,
+ target_link: Optional[str] = None,
+ tolerance: Union[float, Tuple[float, float, float]] = 0.001,
+ weight: float = 1.0,
+ parameterization: int = 0, # 0: Euler, 1: Rotation Vector
+ ) -> OrientationConstraint:
+ """
+ Create a Cartesian orientation constraint of `target_link` with respect to `frame_id`.
+ - `frame_id` defaults to the base link
+ - `target_link` defaults to end effector
+ """
+
+ # Create new position constraint
+ constraint = OrientationConstraint()
+
+ # Define reference frame and target link
+ constraint.header.frame_id = (
+ frame_id if frame_id is not None else self.__base_link_name
+ )
+ constraint.link_name = (
+ target_link if target_link is not None else self.__end_effector_name
+ )
+
+ # Define target orientation
+ if isinstance(quat_xyzw, Quaternion):
+ constraint.orientation = quat_xyzw
+ else:
+ constraint.orientation.x = float(quat_xyzw[0])
+ constraint.orientation.y = float(quat_xyzw[1])
+ constraint.orientation.z = float(quat_xyzw[2])
+ constraint.orientation.w = float(quat_xyzw[3])
+
+ # Define tolerances
+ if type(tolerance) == float:
+ tolerance_xyz = (tolerance, tolerance, tolerance)
+ else:
+ tolerance_xyz = tolerance
+ constraint.absolute_x_axis_tolerance = tolerance_xyz[0]
+ constraint.absolute_y_axis_tolerance = tolerance_xyz[1]
+ constraint.absolute_z_axis_tolerance = tolerance_xyz[2]
+
+ # Define parameterization (how to interpret the tolerance)
+ constraint.parameterization = parameterization
+
+ # Set weight of the constraint
+ constraint.weight = weight
+
+ return constraint
+
+ def set_orientation_goal(
+ self,
+ quat_xyzw: Union[Quaternion, Tuple[float, float, float, float]],
+ frame_id: Optional[str] = None,
+ target_link: Optional[str] = None,
+ tolerance: Union[float, Tuple[float, float, float]] = 0.001,
+ weight: float = 1.0,
+ parameterization: int = 0, # 0: Euler, 1: Rotation Vector
+ ):
+ """
+ Set Cartesian orientation goal of `target_link` with respect to `frame_id`.
+ - `frame_id` defaults to the base link
+ - `target_link` defaults to end effector
+ """
+
+ constraint = self.create_orientation_constraint(
+ quat_xyzw=quat_xyzw,
+ frame_id=frame_id,
+ target_link=target_link,
+ tolerance=tolerance,
+ weight=weight,
+ parameterization=parameterization,
+ )
+
+ # Append to other constraints
+ self.__move_action_goal.request.goal_constraints[
+ -1
+ ].orientation_constraints.append(constraint)
+
+ def create_joint_constraints(
+ self,
+ joint_positions: List[float],
+ joint_names: Optional[List[str]] = None,
+ tolerance: float = 0.001,
+ weight: float = 1.0,
+ ) -> List[JointConstraint]:
+ """
+ Creates joint space constraints. With `joint_names` specified, `joint_positions` can be
+ defined for specific joints in an arbitrary order. Otherwise, first **n** joints
+ passed into the constructor is used, where **n** is the length of `joint_positions`.
+ """
+
+ constraints = []
+
+ # Use default joint names if not specified
+ if joint_names == None:
+ joint_names = self.__joint_names
+
+ for i in range(len(joint_positions)):
+ # Create a new constraint for each joint
+ constraint = JointConstraint()
+
+ # Define joint name
+ constraint.joint_name = joint_names[i]
+
+ # Define the target joint position
+ constraint.position = joint_positions[i]
+
+ # Define telerances
+ constraint.tolerance_above = tolerance
+ constraint.tolerance_below = tolerance
+
+ # Set weight of the constraint
+ constraint.weight = weight
+
+ constraints.append(constraint)
+
+ return constraints
+
+ def set_joint_goal(
+ self,
+ joint_positions: List[float],
+ joint_names: Optional[List[str]] = None,
+ tolerance: float = 0.001,
+ weight: float = 1.0,
+ ):
+ """
+ Set joint space goal. With `joint_names` specified, `joint_positions` can be
+ defined for specific joints in an arbitrary order. Otherwise, first **n** joints
+ passed into the constructor is used, where **n** is the length of `joint_positions`.
+ """
+
+ constraints = self.create_joint_constraints(
+ joint_positions=joint_positions,
+ joint_names=joint_names,
+ tolerance=tolerance,
+ weight=weight,
+ )
+
+ # Append to other constraints
+ self.__move_action_goal.request.goal_constraints[-1].joint_constraints.extend(
+ constraints
+ )
+
+ def clear_goal_constraints(self):
+ """
+ Clear all goal constraints that were previously set.
+ Note that this function is called automatically after each `plan_kinematic_path()`.
+ """
+
+ self.__move_action_goal.request.goal_constraints = [Constraints()]
+
+ def create_new_goal_constraint(self):
+ """
+ Create a new set of goal constraints that will be set together with the request. Each
+ subsequent setting of goals with `set_joint_goal()`, `set_pose_goal()` and others will be
+ added under this newly created set of constraints.
+ """
+
+ self.__move_action_goal.request.goal_constraints.append(Constraints())
+
+ def set_path_joint_constraint(
+ self,
+ joint_positions: List[float],
+ joint_names: Optional[List[str]] = None,
+ tolerance: float = 0.001,
+ weight: float = 1.0,
+ ):
+ """
+ Set joint space path constraints. With `joint_names` specified, `joint_positions` can be
+ defined for specific joints in an arbitrary order. Otherwise, first **n** joints
+ passed into the constructor is used, where **n** is the length of `joint_positions`.
+ """
+
+ constraints = self.create_joint_constraints(
+ joint_positions=joint_positions,
+ joint_names=joint_names,
+ tolerance=tolerance,
+ weight=weight,
+ )
+
+ # Append to other constraints
+ self.__move_action_goal.request.path_constraints.joint_constraints.extend(
+ constraints
+ )
+
+ def set_path_position_constraint(
+ self,
+ position: Union[Point, Tuple[float, float, float]],
+ frame_id: Optional[str] = None,
+ target_link: Optional[str] = None,
+ tolerance: float = 0.001,
+ weight: float = 1.0,
+ ):
+ """
+ Set Cartesian position path constraint of `target_link` with respect to `frame_id`.
+ - `frame_id` defaults to the base link
+ - `target_link` defaults to end effector
+ """
+
+ constraint = self.create_position_constraint(
+ position=position,
+ frame_id=frame_id,
+ target_link=target_link,
+ tolerance=tolerance,
+ weight=weight,
+ )
+
+ # Append to other constraints
+ self.__move_action_goal.request.path_constraints.position_constraints.append(
+ constraint
+ )
+
+ def set_path_orientation_constraint(
+ self,
+ quat_xyzw: Union[Quaternion, Tuple[float, float, float, float]],
+ frame_id: Optional[str] = None,
+ target_link: Optional[str] = None,
+ tolerance: Union[float, Tuple[float, float, float]] = 0.001,
+ weight: float = 1.0,
+ parameterization: int = 0, # 0: Euler Angles, 1: Rotation Vector
+ ):
+ """
+ Set Cartesian orientation path constraint of `target_link` with respect to `frame_id`.
+ - `frame_id` defaults to the base link
+ - `target_link` defaults to end effector
+ """
+
+ constraint = self.create_orientation_constraint(
+ quat_xyzw=quat_xyzw,
+ frame_id=frame_id,
+ target_link=target_link,
+ tolerance=tolerance,
+ weight=weight,
+ parameterization=parameterization,
+ )
+
+ # Append to other constraints
+ self.__move_action_goal.request.path_constraints.orientation_constraints.append(
+ constraint
+ )
+
+ def clear_path_constraints(self):
+ """
+ Clear all path constraints that were previously set.
+ Note that this function is called automatically after each `plan_kinematic_path()`.
+ """
+
+ self.__move_action_goal.request.path_constraints = Constraints()
+
+ def compute_fk(
+ self,
+ joint_state: Optional[Union[JointState, List[float]]] = None,
+ fk_link_names: Optional[List[str]] = None,
+ ) -> Optional[Union[PoseStamped, List[PoseStamped]]]:
+ """
+ Call compute_fk_async and wait on future
+ """
+ future = self.compute_fk_async(
+ **{key: value for key, value in locals().items() if key != "self"}
+ )
+
+ if future is None:
+ return None
+
+ # 100ms sleep
+ rate = self._node.create_rate(10)
+ while not future.done():
+ rate.sleep()
+
+ return self.get_compute_fk_result(future, fk_link_names=fk_link_names)
+
+ def get_compute_fk_result(
+ self,
+ future: Future,
+ fk_link_names: Optional[List[str]] = None,
+ ) -> Optional[Union[PoseStamped, List[PoseStamped]]]:
+ """
+ Takes in a future returned by compute_fk_async and returns the poses
+ if the future is done and successful, else None.
+ """
+ if not future.done():
+ self._node.get_logger().warn(
+ "Cannot get FK result because future is not done."
+ )
+ return None
+
+ res = future.result()
+
+ if MoveItErrorCodes.SUCCESS == res.error_code.val:
+ if fk_link_names is None:
+ return res.pose_stamped[0]
+ else:
+ return res.pose_stamped
+ else:
+ self._node.get_logger().warn(
+ f"FK computation failed! Error code: {res.error_code.val}."
+ )
+ return None
+
+ def compute_fk_async(
+ self,
+ joint_state: Optional[Union[JointState, List[float]]] = None,
+ fk_link_names: Optional[List[str]] = None,
+ ) -> Optional[Future]:
+ """
+ Compute forward kinematics for all `fk_link_names` in a given `joint_state`.
+ - `fk_link_names` defaults to end-effector
+ - `joint_state` defaults to the current joint state
+ """
+
+ if not hasattr(self, "__compute_fk_client"):
+ self.__init_compute_fk()
+
+ if fk_link_names is None:
+ self.__compute_fk_req.fk_link_names = [self.__end_effector_name]
+ else:
+ self.__compute_fk_req.fk_link_names = fk_link_names
+
+ if joint_state is not None:
+ if isinstance(joint_state, JointState):
+ self.__compute_fk_req.robot_state.joint_state = joint_state
+ else:
+ self.__compute_fk_req.robot_state.joint_state = init_joint_state(
+ joint_names=self.__joint_names,
+ joint_positions=joint_state,
+ )
+ elif self.joint_state is not None:
+ self.__compute_fk_req.robot_state.joint_state = self.joint_state
+
+ stamp = self._node.get_clock().now().to_msg()
+ self.__compute_fk_req.header.stamp = stamp
+
+ if not self.__compute_fk_client.service_is_ready():
+ self._node.get_logger().warn(
+ f"Service '{self.__compute_fk_client.srv_name}' is not yet available. Better luck next time!"
+ )
+ return None
+
+ return self.__compute_fk_client.call_async(self.__compute_fk_req)
+
+ def compute_ik(
+ self,
+ position: Union[Point, Tuple[float, float, float]],
+ quat_xyzw: Union[Quaternion, Tuple[float, float, float, float]],
+ start_joint_state: Optional[Union[JointState, List[float]]] = None,
+ constraints: Optional[Constraints] = None,
+ wait_for_server_timeout_sec: Optional[float] = 1.0,
+ ) -> Optional[JointState]:
+ """
+ Call compute_ik_async and wait on future
+ """
+ future = self.compute_ik_async(
+ **{key: value for key, value in locals().items() if key != "self"}
+ )
+
+ if future is None:
+ return None
+
+ # 10ms sleep
+ rate = self._node.create_rate(10)
+ while not future.done():
+ rate.sleep()
+
+ return self.get_compute_ik_result(future)
+
+ def get_compute_ik_result(
+ self,
+ future: Future,
+ ) -> Optional[JointState]:
+ """
+ Takes in a future returned by compute_ik_async and returns the joint states
+ if the future is done and successful, else None.
+ """
+ if not future.done():
+ self._node.get_logger().warn(
+ "Cannot get IK result because future is not done."
+ )
+ return None
+
+ res = future.result()
+
+ if MoveItErrorCodes.SUCCESS == res.error_code.val:
+ return res.solution.joint_state
+ else:
+ self._node.get_logger().warn(
+ f"IK computation failed! Error code: {res.error_code.val}."
+ )
+ return None
+
+ def compute_ik_async(
+ self,
+ position: Union[Point, Tuple[float, float, float]],
+ quat_xyzw: Union[Quaternion, Tuple[float, float, float, float]],
+ start_joint_state: Optional[Union[JointState, List[float]]] = None,
+ constraints: Optional[Constraints] = None,
+ wait_for_server_timeout_sec: Optional[float] = 1.0,
+ ) -> Optional[Future]:
+ """
+ Compute inverse kinematics for the given pose. To indicate beginning of the search space,
+ `start_joint_state` can be specified. Furthermore, `constraints` can be imposed on the
+ computed IK.
+ - `start_joint_state` defaults to current joint state.
+ - `constraints` defaults to None.
+ """
+
+ if not hasattr(self, "__compute_ik_client"):
+ self.__init_compute_ik()
+
+ if isinstance(position, Point):
+ self.__compute_ik_req.ik_request.pose_stamped.pose.position = position
+ else:
+ self.__compute_ik_req.ik_request.pose_stamped.pose.position.x = float(
+ position[0]
+ )
+ self.__compute_ik_req.ik_request.pose_stamped.pose.position.y = float(
+ position[1]
+ )
+ self.__compute_ik_req.ik_request.pose_stamped.pose.position.z = float(
+ position[2]
+ )
+ if isinstance(quat_xyzw, Quaternion):
+ self.__compute_ik_req.ik_request.pose_stamped.pose.orientation = quat_xyzw
+ else:
+ self.__compute_ik_req.ik_request.pose_stamped.pose.orientation.x = float(
+ quat_xyzw[0]
+ )
+ self.__compute_ik_req.ik_request.pose_stamped.pose.orientation.y = float(
+ quat_xyzw[1]
+ )
+ self.__compute_ik_req.ik_request.pose_stamped.pose.orientation.z = float(
+ quat_xyzw[2]
+ )
+ self.__compute_ik_req.ik_request.pose_stamped.pose.orientation.w = float(
+ quat_xyzw[3]
+ )
+
+ if start_joint_state is not None:
+ if isinstance(start_joint_state, JointState):
+ self.__compute_ik_req.ik_request.robot_state.joint_state = (
+ start_joint_state
+ )
+ else:
+ self.__compute_ik_req.ik_request.robot_state.joint_state = (
+ init_joint_state(
+ joint_names=self.__joint_names,
+ joint_positions=start_joint_state,
+ )
+ )
+ elif self.joint_state is not None:
+ self.__compute_ik_req.ik_request.robot_state.joint_state = self.joint_state
+
+ if constraints is not None:
+ self.__compute_ik_req.ik_request.constraints = constraints
+
+ stamp = self._node.get_clock().now().to_msg()
+ self.__compute_ik_req.ik_request.pose_stamped.header.stamp = stamp
+
+ if not self.__compute_ik_client.wait_for_service(
+ timeout_sec=wait_for_server_timeout_sec
+ ):
+ self._node.get_logger().warn(
+ f"Service '{self.__compute_ik_client.srv_name}' is not yet available. Better luck next time!"
+ )
+ return None
+
+ return self.__compute_ik_client.call_async(self.__compute_ik_req)
+
+ def reset_new_joint_state_checker(self):
+ """
+ Reset checker of the new joint state.
+ """
+
+ self.__joint_state_mutex.acquire()
+ self.__new_joint_state_available = False
+ self.__joint_state_mutex.release()
+
+ def force_reset_executing_state(self):
+ """
+ Force reset of internal states that block execution while `ignore_new_calls_while_executing` is being
+ used. This function is applicable only in a very few edge-cases, so it should almost never be used.
+ """
+
+ self.__execution_mutex.acquire()
+ self.__is_motion_requested = False
+ self.__is_executing = False
+ self.__execution_mutex.release()
+
+ def add_collision_primitive(
+ self,
+ id: str,
+ primitive_type: int,
+ dimensions: Tuple[float, float, float],
+ pose: Optional[Union[PoseStamped, Pose]] = None,
+ position: Optional[Union[Point, Tuple[float, float, float]]] = None,
+ quat_xyzw: Optional[
+ Union[Quaternion, Tuple[float, float, float, float]]
+ ] = None,
+ frame_id: Optional[str] = None,
+ operation: int = CollisionObject.ADD,
+ ):
+ """
+ Add collision object with a primitive geometry specified by its dimensions.
+
+ `primitive_type` can be one of the following:
+ - `SolidPrimitive.BOX`
+ - `SolidPrimitive.SPHERE`
+ - `SolidPrimitive.CYLINDER`
+ - `SolidPrimitive.CONE`
+ """
+
+ if (pose is None) and (position is None or quat_xyzw is None):
+ raise ValueError(
+ "Either `pose` or `position` and `quat_xyzw` must be specified!"
+ )
+
+ if isinstance(pose, PoseStamped):
+ pose_stamped = pose
+ elif isinstance(pose, Pose):
+ pose_stamped = PoseStamped(
+ header=Header(
+ stamp=self._node.get_clock().now().to_msg(),
+ frame_id=(
+ frame_id if frame_id is not None else self.__base_link_name
+ ),
+ ),
+ pose=pose,
+ )
+ else:
+ if not isinstance(position, Point):
+ position = Point(
+ x=float(position[0]), y=float(position[1]), z=float(position[2])
+ )
+ if not isinstance(quat_xyzw, Quaternion):
+ quat_xyzw = Quaternion(
+ x=float(quat_xyzw[0]),
+ y=float(quat_xyzw[1]),
+ z=float(quat_xyzw[2]),
+ w=float(quat_xyzw[3]),
+ )
+ pose_stamped = PoseStamped(
+ header=Header(
+ stamp=self._node.get_clock().now().to_msg(),
+ frame_id=(
+ frame_id if frame_id is not None else self.__base_link_name
+ ),
+ ),
+ pose=Pose(position=position, orientation=quat_xyzw),
+ )
+
+ msg = CollisionObject(
+ header=pose_stamped.header,
+ id=id,
+ operation=operation,
+ pose=pose_stamped.pose,
+ )
+
+ msg.primitives.append(
+ SolidPrimitive(type=primitive_type, dimensions=dimensions)
+ )
+
+ self.__collision_object_publisher.publish(msg)
+
+ def add_collision_box(
+ self,
+ id: str,
+ size: Tuple[float, float, float],
+ pose: Optional[Union[PoseStamped, Pose]] = None,
+ position: Optional[Union[Point, Tuple[float, float, float]]] = None,
+ quat_xyzw: Optional[
+ Union[Quaternion, Tuple[float, float, float, float]]
+ ] = None,
+ frame_id: Optional[str] = None,
+ operation: int = CollisionObject.ADD,
+ ):
+ """
+ Add collision object with a box geometry specified by its size.
+ """
+
+ assert len(size) == 3, "Invalid size of the box!"
+
+ self.add_collision_primitive(
+ id=id,
+ primitive_type=SolidPrimitive.BOX,
+ dimensions=size,
+ pose=pose,
+ position=position,
+ quat_xyzw=quat_xyzw,
+ frame_id=frame_id,
+ operation=operation,
+ )
+
+ def add_collision_sphere(
+ self,
+ id: str,
+ radius: float,
+ pose: Optional[Union[PoseStamped, Pose]] = None,
+ position: Optional[Union[Point, Tuple[float, float, float]]] = None,
+ quat_xyzw: Optional[
+ Union[Quaternion, Tuple[float, float, float, float]]
+ ] = None,
+ frame_id: Optional[str] = None,
+ operation: int = CollisionObject.ADD,
+ ):
+ """
+ Add collision object with a sphere geometry specified by its radius.
+ """
+
+ if quat_xyzw is None:
+ quat_xyzw = Quaternion(x=0.0, y=0.0, z=0.0, w=1.0)
+
+ self.add_collision_primitive(
+ id=id,
+ primitive_type=SolidPrimitive.SPHERE,
+ dimensions=[
+ radius,
+ ],
+ pose=pose,
+ position=position,
+ quat_xyzw=quat_xyzw,
+ frame_id=frame_id,
+ operation=operation,
+ )
+
+ def add_collision_cylinder(
+ self,
+ id: str,
+ height: float,
+ radius: float,
+ pose: Optional[Union[PoseStamped, Pose]] = None,
+ position: Optional[Union[Point, Tuple[float, float, float]]] = None,
+ quat_xyzw: Optional[
+ Union[Quaternion, Tuple[float, float, float, float]]
+ ] = None,
+ frame_id: Optional[str] = None,
+ operation: int = CollisionObject.ADD,
+ ):
+ """
+ Add collision object with a cylinder geometry specified by its height and radius.
+ """
+
+ self.add_collision_primitive(
+ id=id,
+ primitive_type=SolidPrimitive.CYLINDER,
+ dimensions=[height, radius],
+ pose=pose,
+ position=position,
+ quat_xyzw=quat_xyzw,
+ frame_id=frame_id,
+ operation=operation,
+ )
+
+ def add_collision_cone(
+ self,
+ id: str,
+ height: float,
+ radius: float,
+ pose: Optional[Union[PoseStamped, Pose]] = None,
+ position: Optional[Union[Point, Tuple[float, float, float]]] = None,
+ quat_xyzw: Optional[
+ Union[Quaternion, Tuple[float, float, float, float]]
+ ] = None,
+ frame_id: Optional[str] = None,
+ operation: int = CollisionObject.ADD,
+ ):
+ """
+ Add collision object with a cone geometry specified by its height and radius.
+ """
+
+ self.add_collision_primitive(
+ id=id,
+ primitive_type=SolidPrimitive.CONE,
+ dimensions=[height, radius],
+ pose=pose,
+ position=position,
+ quat_xyzw=quat_xyzw,
+ frame_id=frame_id,
+ operation=operation,
+ )
+
+ def add_collision_mesh(
+ self,
+ filepath: Optional[str],
+ id: str,
+ pose: Optional[Union[PoseStamped, Pose]] = None,
+ position: Optional[Union[Point, Tuple[float, float, float]]] = None,
+ quat_xyzw: Optional[
+ Union[Quaternion, Tuple[float, float, float, float]]
+ ] = None,
+ frame_id: Optional[str] = None,
+ operation: int = CollisionObject.ADD,
+ scale: Union[float, Tuple[float, float, float]] = 1.0,
+ mesh: Optional[Any] = None,
+ ):
+ """
+ Add collision object with a mesh geometry. Either `filepath` must be
+ specified or `mesh` must be provided.
+ Note: This function required 'trimesh' Python module to be installed.
+ """
+
+ # Load the mesh
+ try:
+ import trimesh
+ except ImportError as err:
+ raise ImportError(
+ "Python module 'trimesh' not found! Please install it manually in order "
+ "to add collision objects into the MoveIt 2 planning scene."
+ ) from err
+
+ # Check the parameters
+ if (pose is None) and (position is None or quat_xyzw is None):
+ raise ValueError(
+ "Either `pose` or `position` and `quat_xyzw` must be specified!"
+ )
+ if (filepath is None and mesh is None) or (
+ filepath is not None and mesh is not None
+ ):
+ raise ValueError("Exactly one of `filepath` or `mesh` must be specified!")
+ if mesh is not None and not isinstance(mesh, trimesh.Trimesh):
+ raise ValueError("`mesh` must be an instance of `trimesh.Trimesh`!")
+
+ if isinstance(pose, PoseStamped):
+ pose_stamped = pose
+ elif isinstance(pose, Pose):
+ pose_stamped = PoseStamped(
+ header=Header(
+ stamp=self._node.get_clock().now().to_msg(),
+ frame_id=(
+ frame_id if frame_id is not None else self.__base_link_name
+ ),
+ ),
+ pose=pose,
+ )
+ else:
+ if not isinstance(position, Point):
+ position = Point(
+ x=float(position[0]), y=float(position[1]), z=float(position[2])
+ )
+ if not isinstance(quat_xyzw, Quaternion):
+ quat_xyzw = Quaternion(
+ x=float(quat_xyzw[0]),
+ y=float(quat_xyzw[1]),
+ z=float(quat_xyzw[2]),
+ w=float(quat_xyzw[3]),
+ )
+ pose_stamped = PoseStamped(
+ header=Header(
+ stamp=self._node.get_clock().now().to_msg(),
+ frame_id=(
+ frame_id if frame_id is not None else self.__base_link_name
+ ),
+ ),
+ pose=Pose(position=position, orientation=quat_xyzw),
+ )
+
+ msg = CollisionObject(
+ header=pose_stamped.header,
+ id=id,
+ operation=operation,
+ pose=pose_stamped.pose,
+ )
+
+ if filepath is not None:
+ mesh = trimesh.load(filepath)
+
+ # Scale the mesh
+ if isinstance(scale, float):
+ scale = (scale, scale, scale)
+ if not (scale[0] == scale[1] == scale[2] == 1.0):
+ # If the mesh was passed in as a parameter, make a copy of it to
+ # avoid transforming the original.
+ if filepath is not None:
+ mesh = mesh.copy()
+ # Transform the mesh
+ transform = np.eye(4)
+ np.fill_diagonal(transform, scale)
+ mesh.apply_transform(transform)
+
+ msg.meshes.append(
+ Mesh(
+ triangles=[MeshTriangle(vertex_indices=face) for face in mesh.faces],
+ vertices=[
+ Point(x=vert[0], y=vert[1], z=vert[2]) for vert in mesh.vertices
+ ],
+ )
+ )
+
+ self.__collision_object_publisher.publish(msg)
+
+ def remove_collision_object(self, id: str):
+ """
+ Remove collision object specified by its `id`.
+ """
+
+ msg = CollisionObject()
+ msg.id = id
+ msg.operation = CollisionObject.REMOVE
+ msg.header.stamp = self._node.get_clock().now().to_msg()
+ self.__collision_object_publisher.publish(msg)
+
+ def remove_collision_mesh(self, id: str):
+ """
+ Remove collision mesh specified by its `id`.
+ Identical to `remove_collision_object()`.
+ """
+
+ self.remove_collision_object(id)
+
+ def attach_collision_object(
+ self,
+ id: str,
+ link_name: Optional[str] = None,
+ touch_links: List[str] = [],
+ weight: float = 0.0,
+ ):
+ """
+ Attach collision object to the robot.
+ """
+
+ if link_name is None:
+ link_name = self.__end_effector_name
+
+ msg = AttachedCollisionObject(
+ object=CollisionObject(id=id, operation=CollisionObject.ADD)
+ )
+ msg.link_name = link_name
+ msg.touch_links = touch_links
+ msg.weight = weight
+
+ self.__attached_collision_object_publisher.publish(msg)
+
+ def detach_collision_object(self, id: int):
+ """
+ Detach collision object from the robot.
+ """
+
+ msg = AttachedCollisionObject(
+ object=CollisionObject(id=id, operation=CollisionObject.REMOVE)
+ )
+ self.__attached_collision_object_publisher.publish(msg)
+
+ def detach_all_collision_objects(self):
+ """
+ Detach collision object from the robot.
+ """
+
+ msg = AttachedCollisionObject(
+ object=CollisionObject(operation=CollisionObject.REMOVE)
+ )
+ self.__attached_collision_object_publisher.publish(msg)
+
+ def move_collision(
+ self,
+ id: str,
+ position: Union[Point, Tuple[float, float, float]],
+ quat_xyzw: Union[Quaternion, Tuple[float, float, float, float]],
+ frame_id: Optional[str] = None,
+ ):
+ """
+ Move collision object specified by its `id`.
+ """
+
+ msg = CollisionObject()
+
+ if not isinstance(position, Point):
+ position = Point(
+ x=float(position[0]), y=float(position[1]), z=float(position[2])
+ )
+ if not isinstance(quat_xyzw, Quaternion):
+ quat_xyzw = Quaternion(
+ x=float(quat_xyzw[0]),
+ y=float(quat_xyzw[1]),
+ z=float(quat_xyzw[2]),
+ w=float(quat_xyzw[3]),
+ )
+
+ pose = Pose()
+ pose.position = position
+ pose.orientation = quat_xyzw
+ msg.pose = pose
+ msg.id = id
+ msg.operation = CollisionObject.MOVE
+ msg.header.frame_id = (
+ frame_id if frame_id is not None else self.__base_link_name
+ )
+ msg.header.stamp = self._node.get_clock().now().to_msg()
+
+ self.__collision_object_publisher.publish(msg)
+
+ def update_planning_scene(self) -> bool:
+ """
+ Gets the current planning scene. Returns whether the service call was
+ successful.
+ """
+
+ if not self._get_planning_scene_service.service_is_ready():
+ self._node.get_logger().warn(
+ f"Service '{self._get_planning_scene_service.srv_name}' is not yet available. Better luck next time!"
+ )
+ return False
+ self.__planning_scene = self._get_planning_scene_service.call(
+ GetPlanningScene.Request()
+ ).scene
+ return True
+
+ def allow_collisions(self, id: str, allow: bool) -> Optional[Future]:
+ """
+ Takes in the ID of an element in the planning scene. Modifies the allowed
+ collision matrix to (dis)allow collisions between that object and all other
+ object.
+
+ If `allow` is True, a plan will succeed even if the robot collides with that object.
+ If `allow` is False, a plan will fail if the robot collides with that object.
+ Returns whether it successfully updated the allowed collision matrix.
+
+ Returns the future of the service call.
+ """
+ # Update the planning scene
+ if not self.update_planning_scene():
+ return None
+ allowed_collision_matrix = self.__planning_scene.allowed_collision_matrix
+ self.__old_allowed_collision_matrix = copy.deepcopy(allowed_collision_matrix)
+
+ # Get the location in the allowed collision matrix of the object
+ j = None
+ if id not in allowed_collision_matrix.entry_names:
+ allowed_collision_matrix.entry_names.append(id)
+ else:
+ j = allowed_collision_matrix.entry_names.index(id)
+ # For all other objects, (dis)allow collisions with the object with `id`
+ for i in range(len(allowed_collision_matrix.entry_values)):
+ if j is None:
+ allowed_collision_matrix.entry_values[i].enabled.append(allow)
+ elif i != j:
+ allowed_collision_matrix.entry_values[i].enabled[j] = allow
+ # For the object with `id`, (dis)allow collisions with all other objects
+ allowed_collision_entry = AllowedCollisionEntry(
+ enabled=[allow for _ in range(len(allowed_collision_matrix.entry_names))]
+ )
+ if j is None:
+ allowed_collision_matrix.entry_values.append(allowed_collision_entry)
+ else:
+ allowed_collision_matrix.entry_values[j] = allowed_collision_entry
+
+ # Apply the new planning scene
+ if not self._apply_planning_scene_service.service_is_ready():
+ self._node.get_logger().warn(
+ f"Service '{self._apply_planning_scene_service.srv_name}' is not yet available. Better luck next time!"
+ )
+ return None
+ return self._apply_planning_scene_service.call_async(
+ ApplyPlanningScene.Request(scene=self.__planning_scene)
+ )
+
+ def process_allow_collision_future(self, future: Future) -> bool:
+ """
+ Return whether the allow collision service call is done and has succeeded
+ or not. If it failed, reset the allowed collision matrix to the old one.
+ """
+ if not future.done():
+ return False
+
+ # Get response
+ resp = future.result()
+
+ # If it failed, restore the old planning scene
+ if not resp.success:
+ self.__planning_scene.allowed_collision_matrix = (
+ self.__old_allowed_collision_matrix
+ )
+
+ return resp.success
+
+ def clear_all_collision_objects(self) -> Optional[Future]:
+ """
+ Removes all attached and un-attached collision objects from the planning scene.
+
+ Returns a future for the ApplyPlanningScene service call.
+ """
+ # Update the planning scene
+ if not self.update_planning_scene():
+ return None
+ self.__old_planning_scene = copy.deepcopy(self.__planning_scene)
+
+ # Remove all collision objects from the planning scene
+ self.__planning_scene.world.collision_objects = []
+ self.__planning_scene.robot_state.attached_collision_objects = []
+
+ # Apply the new planning scene
+ if not self._apply_planning_scene_service.service_is_ready():
+ self._node.get_logger().warn(
+ f"Service '{self._apply_planning_scene_service.srv_name}' is not yet available. Better luck next time!"
+ )
+ return None
+ return self._apply_planning_scene_service.call_async(
+ ApplyPlanningScene.Request(scene=self.__planning_scene)
+ )
+
+ def cancel_clear_all_collision_objects_future(self, future: Future):
+ """
+ Cancel the clear all collision objects service call.
+ """
+ self._apply_planning_scene_service.remove_pending_request(future)
+
+ def process_clear_all_collision_objects_future(self, future: Future) -> bool:
+ """
+ Return whether the clear all collision objects service call is done and has succeeded
+ or not. If it failed, restore the old planning scene.
+ """
+ if not future.done():
+ return False
+
+ # Get response
+ resp = future.result()
+
+ # If it failed, restore the old planning scene
+ if not resp.success:
+ self.__planning_scene = self.__old_planning_scene
+
+ return resp.success
+
+ def __joint_state_callback(self, msg: JointState):
+ # Update only if all relevant joints are included in the message
+ for joint_name in self.joint_names:
+ if not joint_name in msg.name:
+ return
+
+ self.__joint_state_mutex.acquire()
+ self.__joint_state = msg
+ self.__new_joint_state_available = True
+ self.__joint_state_mutex.release()
+
+ def _plan_kinematic_path(self) -> Optional[Future]:
+ # Reuse request from move action goal
+ self.__kinematic_path_request.motion_plan_request = (
+ self.__move_action_goal.request
+ )
+
+ stamp = self._node.get_clock().now().to_msg()
+ self.__kinematic_path_request.motion_plan_request.workspace_parameters.header.stamp = (
+ stamp
+ )
+ for (
+ constraints
+ ) in self.__kinematic_path_request.motion_plan_request.goal_constraints:
+ for position_constraint in constraints.position_constraints:
+ position_constraint.header.stamp = stamp
+ for orientation_constraint in constraints.orientation_constraints:
+ orientation_constraint.header.stamp = stamp
+
+ if not self._plan_kinematic_path_service.service_is_ready():
+ self._node.get_logger().warn(
+ f"Service '{self._plan_kinematic_path_service.srv_name}' is not yet available. Better luck next time!"
+ )
+ return None
+
+ return self._plan_kinematic_path_service.call_async(
+ self.__kinematic_path_request
+ )
+
+ def _plan_cartesian_path(
+ self,
+ max_step: float = 0.0025,
+ frame_id: Optional[str] = None,
+ ) -> Optional[Future]:
+ # Reuse request from move action goal
+ self.__cartesian_path_request.start_state = (
+ self.__move_action_goal.request.start_state
+ )
+
+ # The below attributes were introduced in Iron and do not exist in Humble.
+ if hasattr(self.__cartesian_path_request, "max_velocity_scaling_factor"):
+ self.__cartesian_path_request.max_velocity_scaling_factor = (
+ self.__move_action_goal.request.max_velocity_scaling_factor
+ )
+ if hasattr(self.__cartesian_path_request, "max_acceleration_scaling_factor"):
+ self.__cartesian_path_request.max_acceleration_scaling_factor = (
+ self.__move_action_goal.request.max_acceleration_scaling_factor
+ )
+
+ self.__cartesian_path_request.group_name = (
+ self.__move_action_goal.request.group_name
+ )
+ self.__cartesian_path_request.link_name = self.__end_effector_name
+ self.__cartesian_path_request.max_step = max_step
+
+ self.__cartesian_path_request.header.frame_id = (
+ frame_id if frame_id is not None else self.__base_link_name
+ )
+
+ stamp = self._node.get_clock().now().to_msg()
+ self.__cartesian_path_request.header.stamp = stamp
+
+ self.__cartesian_path_request.path_constraints = (
+ self.__move_action_goal.request.path_constraints
+ )
+ for (
+ position_constraint
+ ) in self.__cartesian_path_request.path_constraints.position_constraints:
+ position_constraint.header.stamp = stamp
+ for (
+ orientation_constraint
+ ) in self.__cartesian_path_request.path_constraints.orientation_constraints:
+ orientation_constraint.header.stamp = stamp
+ # no header in joint_constraint message type
+
+ target_pose = Pose()
+ target_pose.position = (
+ self.__move_action_goal.request.goal_constraints[-1]
+ .position_constraints[-1]
+ .constraint_region.primitive_poses[0]
+ .position
+ )
+ target_pose.orientation = (
+ self.__move_action_goal.request.goal_constraints[-1]
+ .orientation_constraints[-1]
+ .orientation
+ )
+
+ self.__cartesian_path_request.waypoints = [target_pose]
+
+ if not self._plan_cartesian_path_service.service_is_ready():
+ self._node.get_logger().warn(
+ f"Service '{self._plan_cartesian_path_service.srv_name}' is not yet available. Better luck next time!"
+ )
+ return None
+
+ return self._plan_cartesian_path_service.call_async(
+ self.__cartesian_path_request
+ )
+
+ def _send_goal_async_move_action(self):
+ self.__execution_mutex.acquire()
+ stamp = self._node.get_clock().now().to_msg()
+ self.__move_action_goal.request.workspace_parameters.header.stamp = stamp
+ if not self.__move_action_client.server_is_ready():
+ self._node.get_logger().warn(
+ f"Action server '{self.__move_action_client._action_name}' is not yet available. Better luck next time!"
+ )
+ return
+
+ self.__last_error_code = None
+ self.__is_motion_requested = True
+ self.__send_goal_future_move_action = self.__move_action_client.send_goal_async(
+ goal=self.__move_action_goal,
+ feedback_callback=None,
+ )
+
+ self.__send_goal_future_move_action.add_done_callback(
+ self.__response_callback_move_action
+ )
+
+ self.__execution_mutex.release()
+
+ def __response_callback_move_action(self, response):
+ self.__execution_mutex.acquire()
+ goal_handle = response.result()
+ if not goal_handle.accepted:
+ self._node.get_logger().warn(
+ f"Action '{self.__move_action_client._action_name}' was rejected."
+ )
+ self.__is_motion_requested = False
+ return
+
+ self.__execution_goal_handle = goal_handle
+ self.__is_executing = True
+ self.__is_motion_requested = False
+
+ self.__get_result_future_move_action = goal_handle.get_result_async()
+ self.__get_result_future_move_action.add_done_callback(
+ self.__result_callback_move_action
+ )
+ self.__execution_mutex.release()
+
+ def __result_callback_move_action(self, res):
+ self.__execution_mutex.acquire()
+ if res.result().status != GoalStatus.STATUS_SUCCEEDED:
+ self._node.get_logger().warn(
+ f"Action '{self.__move_action_client._action_name}' was unsuccessful: {res.result().status}."
+ )
+ self.motion_suceeded = False
+ else:
+ self.motion_suceeded = True
+
+ self.__last_error_code = res.result().result.error_code
+
+ self.__execution_goal_handle = None
+ self.__is_executing = False
+ self.__execution_mutex.release()
+
+ def _send_goal_async_execute_trajectory(
+ self,
+ goal: ExecuteTrajectory,
+ wait_until_response: bool = False,
+ ):
+ self.__execution_mutex.acquire()
+
+ if not self._execute_trajectory_action_client.server_is_ready():
+ self._node.get_logger().warn(
+ f"Action server '{self._execute_trajectory_action_client._action_name}' is not yet available. Better luck next time!"
+ )
+ return
+
+ self.__last_error_code = None
+ self.__is_motion_requested = True
+ self.__send_goal_future_execute_trajectory = (
+ self._execute_trajectory_action_client.send_goal_async(
+ goal=goal,
+ feedback_callback=None,
+ )
+ )
+
+ self.__send_goal_future_execute_trajectory.add_done_callback(
+ self.__response_callback_execute_trajectory
+ )
+ self.__execution_mutex.release()
+
+ def __response_callback_execute_trajectory(self, response):
+ self.__execution_mutex.acquire()
+ goal_handle = response.result()
+ if not goal_handle.accepted:
+ self._node.get_logger().warn(
+ f"Action '{self._execute_trajectory_action_client._action_name}' was rejected."
+ )
+ self.__is_motion_requested = False
+ return
+
+ self.__execution_goal_handle = goal_handle
+ self.__is_executing = True
+ self.__is_motion_requested = False
+
+ self.__get_result_future_execute_trajectory = goal_handle.get_result_async()
+ self.__get_result_future_execute_trajectory.add_done_callback(
+ self.__result_callback_execute_trajectory
+ )
+ self.__execution_mutex.release()
+
+ def __response_callback_with_event_set_execute_trajectory(self, response):
+ self.__future_done_event.set()
+
+ def __result_callback_execute_trajectory(self, res):
+ self.__execution_mutex.acquire()
+ if res.result().status != GoalStatus.STATUS_SUCCEEDED:
+ self._node.get_logger().warn(
+ f"Action '{self._execute_trajectory_action_client._action_name}' was unsuccessful: {res.result().status}."
+ )
+ self.motion_suceeded = False
+ else:
+ self.motion_suceeded = True
+
+ self.__last_error_code = res.result().result.error_code
+
+ self.__execution_goal_handle = None
+ self.__is_executing = False
+ self.__execution_mutex.release()
+
+ @classmethod
+ def __init_move_action_goal(
+ cls, frame_id: str, group_name: str, end_effector: str
+ ) -> MoveGroup.Goal:
+ move_action_goal = MoveGroup.Goal()
+ move_action_goal.request.workspace_parameters.header.frame_id = frame_id
+ # move_action_goal.request.workspace_parameters.header.stamp = "Set during request"
+ move_action_goal.request.workspace_parameters.min_corner.x = -1.0
+ move_action_goal.request.workspace_parameters.min_corner.y = -1.0
+ move_action_goal.request.workspace_parameters.min_corner.z = -1.0
+ move_action_goal.request.workspace_parameters.max_corner.x = 1.0
+ move_action_goal.request.workspace_parameters.max_corner.y = 1.0
+ move_action_goal.request.workspace_parameters.max_corner.z = 1.0
+ # move_action_goal.request.start_state = "Set during request"
+ move_action_goal.request.goal_constraints = [Constraints()]
+ move_action_goal.request.path_constraints = Constraints()
+ # move_action_goal.request.trajectory_constraints = "Ignored"
+ # move_action_goal.request.reference_trajectories = "Ignored"
+ move_action_goal.request.pipeline_id = ""
+ move_action_goal.request.planner_id = ""
+ move_action_goal.request.group_name = group_name
+ move_action_goal.request.num_planning_attempts = 3
+ move_action_goal.request.allowed_planning_time = 0.5
+ move_action_goal.request.max_velocity_scaling_factor = 0.0
+ move_action_goal.request.max_acceleration_scaling_factor = 0.0
+ # Note: Attribute was renamed in Iron (https://github.com/ros-planning/moveit_msgs/pull/130)
+ if hasattr(move_action_goal.request, "cartesian_speed_limited_link"):
+ move_action_goal.request.cartesian_speed_limited_link = end_effector
+ else:
+ move_action_goal.request.cartesian_speed_end_effector_link = end_effector
+ move_action_goal.request.max_cartesian_speed = 0.0
+
+ # move_action_goal.planning_options.planning_scene_diff = "Ignored"
+ move_action_goal.planning_options.plan_only = False
+ # move_action_goal.planning_options.look_around = "Ignored"
+ # move_action_goal.planning_options.look_around_attempts = "Ignored"
+ # move_action_goal.planning_options.max_safe_execution_cost = "Ignored"
+ # move_action_goal.planning_options.replan = "Ignored"
+ # move_action_goal.planning_options.replan_attempts = "Ignored"
+ # move_action_goal.planning_options.replan_delay = "Ignored"
+
+ return move_action_goal
+
+ def __init_compute_fk(self):
+ self.__compute_fk_client = self._node.create_client(
+ srv_type=GetPositionFK,
+ srv_name="/compute_fk",
+ callback_group=self._callback_group,
+ )
+
+ self.__compute_fk_req = GetPositionFK.Request()
+ self.__compute_fk_req.header.frame_id = self.__base_link_name
+ # self.__compute_fk_req.header.stamp = "Set during request"
+ # self.__compute_fk_req.fk_link_names = "Set during request"
+ # self.__compute_fk_req.robot_state.joint_state = "Set during request"
+ # self.__compute_fk_req.robot_state.multi_dof_ = "Ignored"
+ # self.__compute_fk_req.robot_state.attached_collision_objects = "Ignored"
+ self.__compute_fk_req.robot_state.is_diff = False
+
+ def __init_compute_ik(self):
+ # Service client for IK
+ self.__compute_ik_client = self._node.create_client(
+ srv_type=GetPositionIK,
+ srv_name="/compute_ik",
+ callback_group=self._callback_group,
+ )
+
+ self.__compute_ik_req = GetPositionIK.Request()
+ self.__compute_ik_req.ik_request.group_name = self.__group_name
+ # self.__compute_ik_req.ik_request.robot_state.joint_state = "Set during request"
+ # self.__compute_ik_req.ik_request.robot_state.multi_dof_ = "Ignored"
+ # self.__compute_ik_req.ik_request.robot_state.attached_collision_objects = "Ignored"
+ self.__compute_ik_req.ik_request.robot_state.is_diff = False
+ # self.__compute_ik_req.ik_request.constraints = "Set during request OR Ignored"
+ self.__compute_ik_req.ik_request.avoid_collisions = True
+ # self.__compute_ik_req.ik_request.ik_link_name = "Ignored"
+ self.__compute_ik_req.ik_request.pose_stamped.header.frame_id = (
+ self.__base_link_name
+ )
+ # self.__compute_ik_req.ik_request.pose_stamped.header.stamp = "Set during request"
+ # self.__compute_ik_req.ik_request.pose_stamped.pose = "Set during request"
+ # self.__compute_ik_req.ik_request.ik_link_names = "Ignored"
+ # self.__compute_ik_req.ik_request.pose_stamped_vector = "Ignored"
+ # self.__compute_ik_req.ik_request.timeout.sec = "Ignored"
+ # self.__compute_ik_req.ik_request.timeout.nanosec = "Ignored"
+
+ @property
+ def planning_scene(self) -> Optional[PlanningScene]:
+ return self.__planning_scene
+
+ @property
+ def follow_joint_trajectory_action_client(self) -> str:
+ return self.__follow_joint_trajectory_action_client
+
+ @property
+ def end_effector_name(self) -> str:
+ return self.__end_effector_name
+
+ @property
+ def base_link_name(self) -> str:
+ return self.__base_link_name
+
+ @property
+ def joint_names(self) -> List[str]:
+ return self.__joint_names
+
+ @property
+ def joint_state(self) -> Optional[JointState]:
+ self.__joint_state_mutex.acquire()
+ joint_state = self.__joint_state
+ self.__joint_state_mutex.release()
+ return joint_state
+
+ @property
+ def new_joint_state_available(self):
+ return self.__new_joint_state_available
+
+ @property
+ def max_velocity(self) -> float:
+ return self.__move_action_goal.request.max_velocity_scaling_factor
+
+ @max_velocity.setter
+ def max_velocity(self, value: float):
+ self.__move_action_goal.request.max_velocity_scaling_factor = value
+
+ @property
+ def max_acceleration(self) -> float:
+ return self.__move_action_goal.request.max_acceleration_scaling_factor
+
+ @max_acceleration.setter
+ def max_acceleration(self, value: float):
+ self.__move_action_goal.request.max_acceleration_scaling_factor = value
+
+ @property
+ def num_planning_attempts(self) -> int:
+ return self.__move_action_goal.request.num_planning_attempts
+
+ @num_planning_attempts.setter
+ def num_planning_attempts(self, value: int):
+ self.__move_action_goal.request.num_planning_attempts = value
+
+ @property
+ def allowed_planning_time(self) -> float:
+ return self.__move_action_goal.request.allowed_planning_time
+
+ @allowed_planning_time.setter
+ def allowed_planning_time(self, value: float):
+ self.__move_action_goal.request.allowed_planning_time = value
+
+ @property
+ def cartesian_avoid_collisions(self) -> bool:
+ return self.__cartesian_path_request.request.avoid_collisions
+
+ @cartesian_avoid_collisions.setter
+ def cartesian_avoid_collisions(self, value: bool):
+ self.__cartesian_path_request.avoid_collisions = value
+
+ @property
+ def cartesian_jump_threshold(self) -> float:
+ return self.__cartesian_path_request.request.jump_threshold
+
+ @cartesian_jump_threshold.setter
+ def cartesian_jump_threshold(self, value: float):
+ self.__cartesian_path_request.jump_threshold = value
+
+ @property
+ def cartesian_prismatic_jump_threshold(self) -> float:
+ return self.__cartesian_path_request.request.prismatic_jump_threshold
+
+ @cartesian_prismatic_jump_threshold.setter
+ def cartesian_prismatic_jump_threshold(self, value: float):
+ self.__cartesian_path_request.prismatic_jump_threshold = value
+
+ @property
+ def cartesian_revolute_jump_threshold(self) -> float:
+ return self.__cartesian_path_request.request.revolute_jump_threshold
+
+ @cartesian_revolute_jump_threshold.setter
+ def cartesian_revolute_jump_threshold(self, value: float):
+ self.__cartesian_path_request.revolute_jump_threshold = value
+
+ @property
+ def pipeline_id(self) -> int:
+ return self.__move_action_goal.request.pipeline_id
+
+ @pipeline_id.setter
+ def pipeline_id(self, value: str):
+ self.__move_action_goal.request.pipeline_id = value
+
+ @property
+ def planner_id(self) -> int:
+ return self.__move_action_goal.request.planner_id
+
+ @planner_id.setter
+ def planner_id(self, value: str):
+ self.__move_action_goal.request.planner_id = value
+
+
+def init_joint_state(
+ joint_names: List[str],
+ joint_positions: Optional[List[str]] = None,
+ joint_velocities: Optional[List[str]] = None,
+ joint_effort: Optional[List[str]] = None,
+) -> JointState:
+ joint_state = JointState()
+
+ joint_state.name = joint_names
+ joint_state.position = (
+ joint_positions if joint_positions is not None else [0.0] * len(joint_names)
+ )
+ joint_state.velocity = (
+ joint_velocities if joint_velocities is not None else [0.0] * len(joint_names)
+ )
+ joint_state.effort = (
+ joint_effort if joint_effort is not None else [0.0] * len(joint_names)
+ )
+
+ return joint_state
+
+
+def init_execute_trajectory_goal(
+ joint_trajectory: JointTrajectory,
+) -> Optional[ExecuteTrajectory.Goal]:
+ if joint_trajectory is None:
+ return None
+
+ execute_trajectory_goal = ExecuteTrajectory.Goal()
+
+ execute_trajectory_goal.trajectory.joint_trajectory = joint_trajectory
+
+ return execute_trajectory_goal
+
+
+def init_dummy_joint_trajectory_from_state(
+ joint_state: JointState, duration_sec: int = 0, duration_nanosec: int = 0
+) -> JointTrajectory:
+ joint_trajectory = JointTrajectory()
+ joint_trajectory.joint_names = joint_state.name
+
+ point = JointTrajectoryPoint()
+ point.positions = joint_state.position
+ point.velocities = joint_state.velocity
+ point.accelerations = [0.0] * len(joint_trajectory.joint_names)
+ point.effort = joint_state.effort
+ point.time_from_start.sec = duration_sec
+ point.time_from_start.nanosec = duration_nanosec
+ joint_trajectory.points.append(point)
+
+ return joint_trajectory
diff --git a/unilabos/devices/ros_dev/moveit_interface.py b/unilabos/devices/ros_dev/moveit_interface.py
new file mode 100644
index 0000000..82b9564
--- /dev/null
+++ b/unilabos/devices/ros_dev/moveit_interface.py
@@ -0,0 +1,376 @@
+import json
+import time
+from copy import deepcopy
+from pathlib import Path
+
+from moveit_msgs.msg import JointConstraint, Constraints
+from rclpy.action import ActionClient
+from tf2_ros import Buffer, TransformListener
+from unilabos_msgs.action import SendCmd
+
+from unilabos.devices.ros_dev.moveit2 import MoveIt2
+from unilabos.ros.nodes.base_device_node import BaseROS2DeviceNode
+
+
+class MoveitInterface:
+ _ros_node: BaseROS2DeviceNode
+ tf_buffer: Buffer
+ tf_listener: TransformListener
+
+ def __init__(self, moveit_type, joint_poses, rotation=None, device_config=None):
+ self.device_config = device_config
+ self.rotation = rotation
+ self.data_config = json.load(
+ open(
+ f"{Path(__file__).parent.parent.parent.absolute()}/device_mesh/devices/{moveit_type}/config/move_group.json",
+ encoding="utf-8",
+ )
+ )
+ self.arm_move_flag = False
+ self.move_option = ["pick", "place", "side_pick", "side_place"]
+ self.joint_poses = joint_poses
+ self.cartesian_flag = False
+ self.mesh_group = ["reactor", "sample", "beaker"]
+ self.moveit2 = {}
+ self.resource_action = None
+ self.resource_client = None
+ self.resource_action_ok = False
+
+
+ def post_init(self, ros_node: BaseROS2DeviceNode):
+ self._ros_node = ros_node
+ self.tf_buffer = Buffer()
+ self.tf_listener = TransformListener(self.tf_buffer, self._ros_node)
+
+ for move_group, config in self.data_config.items():
+
+ base_link_name = f"{self._ros_node.device_id}_{config['base_link_name']}"
+ end_effector_name = f"{self._ros_node.device_id}_{config['end_effector_name']}"
+ joint_names = [f"{self._ros_node.device_id}_{name}" for name in config["joint_names"]]
+
+ self.moveit2[f"{move_group}"] = MoveIt2(
+ node=self._ros_node,
+ joint_names=joint_names,
+ base_link_name=base_link_name,
+ end_effector_name=end_effector_name,
+ group_name=f"{self._ros_node.device_id}_{move_group}",
+ callback_group=self._ros_node.callback_group,
+ use_move_group_action=True,
+ ignore_new_calls_while_executing=True,
+ )
+ self.moveit2[f"{move_group}"].allowed_planning_time = 3.0
+
+ self._ros_node.create_timer(1, self.wait_for_resource_action, callback_group=self._ros_node.callback_group)
+
+
+ def wait_for_resource_action(self):
+ if not self.resource_action_ok:
+
+ while self.resource_action is None:
+ self.resource_action = self.check_tf_update_actions()
+ time.sleep(1)
+ self.resource_client = ActionClient(self._ros_node, SendCmd, self.resource_action)
+ self.resource_action_ok = True
+ while not self.resource_client.wait_for_server(timeout_sec=5.0):
+ self._ros_node.lab_logger().info("等待 TfUpdate 服务器...")
+
+ def check_tf_update_actions(self):
+ topics = self._ros_node.get_topic_names_and_types()
+ for topic_item in topics:
+ topic_name, topic_types = topic_item
+ if "action_msgs/msg/GoalStatusArray" in topic_types:
+ # 删除 /_action/status 部分
+
+ base_name = topic_name.replace("/_action/status", "")
+ # 检查最后一个部分是否为 tf_update
+ parts = base_name.split("/")
+ if parts and parts[-1] == "tf_update":
+ return base_name
+
+ return None
+
+ def set_position(self, command):
+ """使用moveit 移动到指定点
+ Args:
+ command: A JSON-formatted string that includes quaternion, speed, position
+
+ position (list) : 点的位置 [x,y,z]
+ quaternion (list) : 点的姿态(四元数) [x,y,z,w]
+ move_group (string) : The move group moveit will plan
+ speed (float) : The speed of the movement, speed > 0
+ retry (int) : Retry times when moveit plan fails
+
+ Returns:
+ None
+ """
+
+ result = SendCmd.Result()
+ cmd_str = command.replace("'", '"')
+ cmd_dict = json.loads(cmd_str)
+ self.moveit_task(**cmd_dict)
+ return result
+
+ def moveit_task(
+ self, move_group, position, quaternion, speed=1, retry=10, cartesian=False, target_link=None, offsets=[0, 0, 0]
+ ):
+
+ speed_ = float(max(0.1, min(speed, 1)))
+
+ self.moveit2[move_group].max_velocity = speed_
+ self.moveit2[move_group].max_acceleration = speed_
+
+ re_ = False
+
+ pose_result = [x + y for x, y in zip(position, offsets)]
+ # print(pose_result)
+
+ while retry > -1 and not re_:
+
+ self.moveit2[move_group].move_to_pose(
+ target_link=target_link,
+ position=pose_result,
+ quat_xyzw=quaternion,
+ cartesian=cartesian,
+ # cartesian_fraction_threshold=0.0,
+ cartesian_max_step=0.01,
+ weight_position=1.0,
+ )
+ re_ = self.moveit2[move_group].wait_until_executed()
+ retry += -1
+
+ return re_
+
+ def moveit_joint_task(self, move_group, joint_positions, joint_names=None, speed=1, retry=10):
+
+ re_ = False
+
+ joint_positions_ = [float(x) for x in joint_positions]
+
+ speed_ = float(max(0.1, min(speed, 1)))
+
+ self.moveit2[move_group].max_velocity = speed_
+ self.moveit2[move_group].max_acceleration = speed_
+
+ while retry > -1 and not re_:
+
+ self.moveit2[move_group].move_to_configuration(joint_positions=joint_positions_, joint_names=joint_names)
+ re_ = self.moveit2[move_group].wait_until_executed()
+
+ retry += -1
+ print(self.moveit2[move_group].compute_fk(joint_positions))
+ return re_
+
+ def resource_manager(self, resource, parent_link):
+ goal_msg = SendCmd.Goal()
+ str_dict = {}
+ str_dict[resource] = parent_link
+
+ goal_msg.command = json.dumps(str_dict)
+ assert self.resource_client is not None
+ self.resource_client.send_goal(goal_msg)
+
+ return True
+
+ def pick_and_place(self, command: str):
+ """
+ Using MoveIt to make the robotic arm pick or place materials to a target point.
+
+ Args:
+ command: A JSON-formatted string that includes option, target, speed, lift_height, mt_height
+
+ *option (string) : Action type: pick/place/side_pick/side_place
+ *move_group (string): The move group moveit will plan
+ *status(string) : Target pose
+ resource(string) : The target resource
+ x_distance (float) : The distance to the target in x direction(meters)
+ y_distance (float) : The distance to the target in y direction(meters)
+ lift_height (float) : The height at which the material should be lifted(meters)
+ retry (float) : Retry times when moveit plan fails
+ speed (float) : The speed of the movement, speed > 0
+ Returns:
+ None
+ """
+ result = SendCmd.Result()
+
+ try:
+ cmd_str = str(command).replace("'", '"')
+ cmd_dict = json.loads(cmd_str)
+
+ if cmd_dict["option"] in self.move_option:
+ option_index = self.move_option.index(cmd_dict["option"])
+ place_flag = option_index % 2
+
+ config = {}
+ function_list = []
+
+ status = cmd_dict["status"]
+ joint_positions_ = self.joint_poses[cmd_dict["move_group"]][status]
+
+ config.update({k: cmd_dict[k] for k in ["speed", "retry", "move_group"] if k in cmd_dict})
+
+ # 夹取
+ if not place_flag:
+ if "target" in cmd_dict.keys():
+ function_list.append(lambda: self.resource_manager(cmd_dict["resource"], cmd_dict["target"]))
+ else:
+ function_list.append(
+ lambda: self.resource_manager(
+ cmd_dict["resource"], self.moveit2[cmd_dict["move_group"]].end_effector_name
+ )
+ )
+ else:
+ function_list.append(lambda: self.resource_manager(cmd_dict["resource"], "world"))
+
+ constraints = []
+ if "constraints" in cmd_dict.keys():
+
+ for i in range(len(cmd_dict["constraints"])):
+ v = float(cmd_dict["constraints"][i])
+ if v > 0:
+ constraints.append(
+ JointConstraint(
+ joint_name=self.moveit2[cmd_dict["move_group"]].joint_names[i],
+ position=joint_positions_[i],
+ tolerance_above=v,
+ tolerance_below=v,
+ weight=1.0,
+ )
+ )
+
+ if "lift_height" in cmd_dict.keys():
+ retval = None
+ retry = config.get("retry", 10)
+ while retval is None and retry > 0:
+ retval = self.moveit2[cmd_dict["move_group"]].compute_fk(joint_positions_)
+ time.sleep(0.1)
+ retry -= 1
+ if retval is None:
+ result.success = False
+ return result
+ pose = [retval.pose.position.x, retval.pose.position.y, retval.pose.position.z]
+ quaternion = [
+ retval.pose.orientation.x,
+ retval.pose.orientation.y,
+ retval.pose.orientation.z,
+ retval.pose.orientation.w,
+ ]
+
+ function_list = [
+ lambda: self.moveit_task(
+ position=[retval.pose.position.x, retval.pose.position.y, retval.pose.position.z],
+ quaternion=quaternion,
+ **config,
+ cartesian=self.cartesian_flag,
+ )
+ ] + function_list
+
+ pose[2] += float(cmd_dict["lift_height"])
+ function_list.append(
+ lambda: self.moveit_task(
+ position=pose, quaternion=quaternion, **config, cartesian=self.cartesian_flag
+ )
+ )
+ end_pose = pose
+
+ if "x_distance" in cmd_dict.keys() or "y_distance" in cmd_dict.keys():
+ if "x_distance" in cmd_dict.keys():
+ deep_pose = deepcopy(pose)
+ deep_pose[0] += float(cmd_dict["x_distance"])
+ elif "y_distance" in cmd_dict.keys():
+ deep_pose = deepcopy(pose)
+ deep_pose[1] += float(cmd_dict["y_distance"])
+
+ function_list = [
+ lambda: self.moveit_task(
+ position=pose, quaternion=quaternion, **config, cartesian=self.cartesian_flag
+ )
+ ] + function_list
+ function_list.append(
+ lambda: self.moveit_task(
+ position=deep_pose, quaternion=quaternion, **config, cartesian=self.cartesian_flag
+ )
+ )
+ end_pose = deep_pose
+
+ retval_ik = self.moveit2[cmd_dict["move_group"]].compute_ik(
+ position=end_pose, quat_xyzw=quaternion, constraints=Constraints(joint_constraints=constraints)
+ )
+ position_ = [
+ retval_ik.position[retval_ik.name.index(i)]
+ for i in self.moveit2[cmd_dict["move_group"]].joint_names
+ ]
+ function_list = [
+ lambda: self.moveit_joint_task(
+ joint_positions=position_,
+ joint_names=self.moveit2[cmd_dict["move_group"]].joint_names,
+ **config,
+ )
+ ] + function_list
+ else:
+ function_list = [
+ lambda: self.moveit_joint_task(**config, joint_positions=joint_positions_)
+ ] + function_list
+
+ for i in range(len(function_list)):
+ if i == 0:
+ self.cartesian_flag = False
+ else:
+ self.cartesian_flag = True
+
+ re = function_list[i]()
+ if not re:
+ print(i, re)
+ result.success = False
+ return result
+ result.success = True
+
+ except Exception as e:
+ print(e)
+ self.cartesian_flag = False
+ result.success = False
+
+ return result
+
+ def set_status(self, command: str):
+ """
+ Goto home position
+
+ Args:
+ command: A JSON-formatted string that includes speed
+ *status (string) : The joint status moveit will plan
+ *move_group (string): The move group moveit will plan
+ separate (list) : The joint index to be separated
+ lift_height (float) : The height at which the material should be lifted(meters)
+ x_distance (float) : The distance to the target in x direction(meters)
+ y_distance (float) : The distance to the target in y direction(meters)
+ speed (float) : The speed of the movement, speed > 0
+ retry (float) : Retry times when moveit plan fails
+
+ Returns:
+ None
+ """
+
+ result = SendCmd.Result()
+
+ try:
+ cmd_str = command.replace("'", '"')
+ cmd_dict = json.loads(cmd_str)
+ config = {}
+ config["move_group"] = cmd_dict["move_group"]
+ if "speed" in cmd_dict.keys():
+ config["speed"] = cmd_dict["speed"]
+ if "retry" in cmd_dict.keys():
+ config["retry"] = cmd_dict["retry"]
+
+ status = cmd_dict["status"]
+ joint_positions_ = self.joint_poses[cmd_dict["move_group"]][status]
+ re = self.moveit_joint_task(**config, joint_positions=joint_positions_)
+ if not re:
+ result.success = False
+ return result
+ result.success = True
+ except Exception as e:
+ print(e)
+ result.success = False
+
+ return result
diff --git a/unilabos/registry/devices/hotel.yaml b/unilabos/registry/devices/hotel.yaml
new file mode 100644
index 0000000..0f92511
--- /dev/null
+++ b/unilabos/registry/devices/hotel.yaml
@@ -0,0 +1,9 @@
+hotel.thermo_orbitor_rs2_hotel:
+ description: Thermo Orbitor RS2 Hotel
+ class:
+ module: unilabos.devices.resource_container.container:HotelContainer
+ type: python
+ model:
+ type: device
+ mesh: thermo_orbitor_rs2_hotel
+
diff --git a/unilabos/registry/devices/liquid_handler.yaml b/unilabos/registry/devices/liquid_handler.yaml
index eef0404..bb94b59 100644
--- a/unilabos/registry/devices/liquid_handler.yaml
+++ b/unilabos/registry/devices/liquid_handler.yaml
@@ -358,8 +358,8 @@ liquid_handler.biomek:
transfer_biomek:
type: LiquidHandlerTransferBiomek
goal:
- source: source
- target: target
+ sources: sources
+ targets: targets
tip_rack: tip_rack
volume: volume
aspirate_techniques: aspirate_techniques
@@ -417,8 +417,8 @@ liquid_handler.biomek:
move_biomek:
type: LiquidHandlerMoveBiomek
goal:
- source: resource
- target: target
+ source: sources
+ target: targets
feedback: {}
result:
name: name
diff --git a/unilabos/registry/devices/moveit_config.yaml b/unilabos/registry/devices/moveit_config.yaml
new file mode 100644
index 0000000..383affc
--- /dev/null
+++ b/unilabos/registry/devices/moveit_config.yaml
@@ -0,0 +1,56 @@
+moveit.toyo_xyz:
+ description: Toyo XYZ
+ class:
+ module: unilabos.devices.ros_dev.moveit_interface:MoveitInterface
+ type: python
+ action_value_mappings:
+ set_position:
+ type: SendCmd
+ goal:
+ command: command
+ feedback: { }
+ result: { }
+ pick_and_place:
+ type: SendCmd
+ goal:
+ command: command
+ feedback: { }
+ result: { }
+ set_status:
+ type: SendCmd
+ goal:
+ command: command
+ feedback: { }
+ result: { }
+
+ model:
+ type: device
+ mesh: toyo_xyz
+
+moveit.benyao_arm:
+ description: Benyao Arm
+ model:
+ type: device
+ mesh: benyao_arm
+ class:
+ module: unilabos.devices.ros_dev.moveit_interface:MoveitInterface
+ type: python
+ action_value_mappings:
+ set_position:
+ type: SendCmd
+ goal:
+ command: command
+ feedback: {}
+ result: {}
+ pick_and_place:
+ type: SendCmd
+ goal:
+ command: command
+ feedback: {}
+ result: {}
+ set_status:
+ type: SendCmd
+ goal:
+ command: command
+ feedback: {}
+ result: {}
diff --git a/unilabos/registry/registry.py b/unilabos/registry/registry.py
index a160272..03d4899 100644
--- a/unilabos/registry/registry.py
+++ b/unilabos/registry/registry.py
@@ -87,7 +87,7 @@ class Registry:
),
"handles": {
"output": [{
- "handler_key": "Labware",
+ "handler_key": "labware",
"label": "Labware",
"data_type": "resource",
"data_source": "handle",
diff --git a/unilabos/resources/graphio.py b/unilabos/resources/graphio.py
index 9a31add..cca7a35 100644
--- a/unilabos/resources/graphio.py
+++ b/unilabos/resources/graphio.py
@@ -9,7 +9,7 @@ try:
from pylabrobot.resources.resource import Resource as ResourcePLR
except ImportError:
pass
-
+from typing import Union, get_origin, get_args
physical_setup_graph: nx.Graph = None
@@ -298,7 +298,6 @@ def nested_dict_to_list(nested_dict: dict) -> list[dict]: # FIXME 是tree?
return result
-
def convert_resources_to_type(
resources_list: list[dict], resource_type: type, *, plr_model: bool = False
) -> Union[list[dict], dict, None, "ResourcePLR"]:
@@ -320,9 +319,13 @@ def convert_resources_to_type(
return resource_ulab_to_plr(resources_list, plr_model)
resources_tree = dict_to_tree({r["id"]: r for r in resources_list})
return resource_ulab_to_plr(resources_tree[0], plr_model)
- elif isinstance(resource_type, list) and all(issubclass(t, ResourcePLR) for t in resource_type):
- resources_tree = dict_to_tree({r["id"]: r for r in resources_list})
- return [resource_ulab_to_plr(r, plr_model) for r in resources_tree]
+ elif isinstance(resource_type, list) :
+ if all((get_origin(t) is Union) for t in resource_type):
+ resources_tree = dict_to_tree({r["id"]: r for r in resources_list})
+ return [resource_ulab_to_plr(r, plr_model) for r in resources_tree]
+ elif all(issubclass(t, ResourcePLR) for t in resource_type):
+ resources_tree = dict_to_tree({r["id"]: r for r in resources_list})
+ return [resource_ulab_to_plr(r, plr_model) for r in resources_tree]
else:
return None
@@ -343,9 +346,13 @@ def convert_resources_from_type(resources_list, resource_type: type) -> Union[li
elif isinstance(resource_type, type) and issubclass(resource_type, ResourcePLR):
resources_tree = [resource_plr_to_ulab(resources_list)]
return tree_to_list(resources_tree)
- elif isinstance(resource_type, list) and all(issubclass(t, ResourcePLR) for t in resource_type):
- resources_tree = [resource_plr_to_ulab(r) for r in resources_list]
- return tree_to_list(resources_tree)
+ elif isinstance(resource_type, list) :
+ if all((get_origin(t) is Union) for t in resource_type):
+ resources_tree = [resource_plr_to_ulab(r) for r in resources_list]
+ return tree_to_list(resources_tree)
+ elif all(issubclass(t, ResourcePLR) for t in resource_type):
+ resources_tree = [resource_plr_to_ulab(r) for r in resources_list]
+ return tree_to_list(resources_tree)
else:
return None
diff --git a/unilabos/ros/main_slave_run.py b/unilabos/ros/main_slave_run.py
index c4c5a17..bbd6359 100644
--- a/unilabos/ros/main_slave_run.py
+++ b/unilabos/ros/main_slave_run.py
@@ -6,9 +6,9 @@ import time
from typing import Optional, Dict, Any, List
import rclpy
-from unilabos.ros.nodes.presets.joint_republisher import JointRepublisher
from unilabos.ros.nodes.presets.resource_mesh_manager import ResourceMeshManager
from unilabos.ros.nodes.resource_tracker import DeviceNodeResourceTracker
+from unilabos.devices.ros_dev.liquid_handler_joint_publisher import LiquidHandlerJointPublisher
from unilabos_msgs.msg import Resource # type: ignore
from unilabos_msgs.srv import ResourceAdd, SerialCommand # type: ignore
from rclpy.executors import MultiThreadedExecutor
@@ -69,19 +69,23 @@ def main(
)
if visual != "disable":
+ from unilabos.ros.nodes.presets.joint_republisher import JointRepublisher
+
resource_mesh_manager = ResourceMeshManager(
resources_mesh_config,
resources_config,
- resource_tracker= DeviceNodeResourceTracker(),
+ resource_tracker = host_node.resource_tracker,
device_id = 'resource_mesh_manager',
)
joint_republisher = JointRepublisher(
'joint_republisher',
- DeviceNodeResourceTracker()
+ host_node.resource_tracker
)
-
+ lh_joint_pub = LiquidHandlerJointPublisher(resources_config=resources_config,
+ resource_tracker=host_node.resource_tracker)
executor.add_node(resource_mesh_manager)
executor.add_node(joint_republisher)
+ executor.add_node(lh_joint_pub)
thread = threading.Thread(target=executor.spin, daemon=True, name="host_executor_thread")
thread.start()
@@ -121,6 +125,7 @@ def slave(
executor.add_node(n)
if visual != "disable":
+ from unilabos.ros.nodes.presets.joint_republisher import JointRepublisher
resource_mesh_manager = ResourceMeshManager(
resources_mesh_config,
resources_config,
diff --git a/unilabos/ros/msgs/message_converter.py b/unilabos/ros/msgs/message_converter.py
index 94b12cf..62ab606 100644
--- a/unilabos/ros/msgs/message_converter.py
+++ b/unilabos/ros/msgs/message_converter.py
@@ -131,7 +131,7 @@ _msg_converter: Dict[Type, Any] = {
Bool: lambda x: Bool(data=bool(x)),
str: str,
String: lambda x: String(data=str(x)),
- Point: lambda x: Point(x=x.x, y=x.y, z=x.z) if not isinstance(x, dict) else Point(x=x.get("x", 0), y=x.get("y", 0), z=x.get("z", 0)),
+ Point: lambda x: Point(x=x.x, y=x.y, z=x.z) if not isinstance(x, dict) else Point(x=x.get("x", 0.0), y=x.get("y", 0.0), z=x.get("z", 0.0)),
Resource: lambda x: Resource(
id=x.get("id", ""),
name=x.get("name", ""),
@@ -141,7 +141,7 @@ _msg_converter: Dict[Type, Any] = {
type=x.get("type", ""),
category=x.get("class", "") or x.get("type", ""),
pose=(
- Pose(position=Point(x=float(x.get("position", {}).get("x", 0)), y=float(x.get("position", {}).get("y", 0)), z=float(x.get("position", {}).get("z", 0))))
+ Pose(position=Point(x=float(x.get("position", {}).get("x", 0.0)), y=float(x.get("position", {}).get("y", 0.0)), z=float(x.get("position", {}).get("z", 0.0))))
if x.get("position", None) is not None
else Pose()
),
diff --git a/unilabos/ros/nodes/base_device_node.py b/unilabos/ros/nodes/base_device_node.py
index 67cdb6f..dcf0759 100644
--- a/unilabos/ros/nodes/base_device_node.py
+++ b/unilabos/ros/nodes/base_device_node.py
@@ -740,16 +740,23 @@ class BaseROS2DeviceNode(Node, Generic[T]):
self.lab_logger().info(f"更新资源状态: {k}")
r = ResourceUpdate.Request()
# 仅当action_kwargs[k]不为None时尝试转换
- akv = action_kwargs[k]
+ akv = action_kwargs[k] # 已经是完成转换的物料了,只需要转换成ros msg Resource了
apv = action_paramtypes[k]
final_type = get_type_class(apv)
if final_type is None:
continue
try:
- r.resources = [
- convert_to_ros_msg(Resource, self.resource_tracker.root_resource(rs))
- for rs in convert_resources_from_type(akv, final_type) # type: ignore # FIXME # 考虑反查到最大的
- ]
+ seen = set()
+ unique_resources = []
+ for rs in akv:
+ res = self.resource_tracker.parent_resource(rs) # 获取 resource 对象
+ if id(res) not in seen:
+ seen.add(id(res))
+ converted_list = convert_resources_from_type([res], final_type)
+ unique_resources.extend([convert_to_ros_msg(Resource, converted) for converted in converted_list])
+
+ r.resources = unique_resources
+
response = await self._resource_clients["resource_update"].call_async(r)
self.lab_logger().debug(f"资源更新结果: {response}")
except Exception as e:
@@ -917,6 +924,12 @@ class ROS2DeviceNode:
)
self._ros_node: BaseROS2DeviceNode
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
+ if hasattr(self.driver_instance, "post_init"):
+ try:
+ self.driver_instance.post_init(self._ros_node) # type: ignore
+ except Exception as e:
+ self._ros_node.lab_logger().error(f"设备后初始化失败: {e}")
def _start_loop(self):
def run_event_loop():
diff --git a/unilabos/ros/nodes/presets/resource_mesh_manager.py b/unilabos/ros/nodes/presets/resource_mesh_manager.py
index c149581..dadb49a 100644
--- a/unilabos/ros/nodes/presets/resource_mesh_manager.py
+++ b/unilabos/ros/nodes/presets/resource_mesh_manager.py
@@ -91,8 +91,11 @@ class ResourceMeshManager(BaseROS2DeviceNode):
self.__collision_object_publisher = self.create_publisher(
CollisionObject, "/collision_object", 10
)
+ self.__planning_scene_publisher = self.create_publisher(
+ PlanningScene, "/planning_scene", 10
+ )
self.__attached_collision_object_publisher = self.create_publisher(
- AttachedCollisionObject, "/attached_collision_object", 10
+ AttachedCollisionObject, "/attached_collision_object", 0
)
# 创建一个Action Server用于修改resource_tf_dict
@@ -121,7 +124,8 @@ class ResourceMeshManager(BaseROS2DeviceNode):
"""检查move_group节点是否已初始化完成"""
# 获取当前可用的节点列表
-
+ if len(self.resource_tf_dict) == 0:
+ return
tf_ready = self.tf_buffer.can_transform("world", next(iter(self.resource_tf_dict.keys())), rclpy.time.Time(),rclpy.duration.Duration(seconds=2))
# if tf_ready:
@@ -129,8 +133,7 @@ class ResourceMeshManager(BaseROS2DeviceNode):
self.move_group_ready = True
self.publish_resource_tf()
self.add_resource_collision_meshes(self.resource_tf_dict)
-
- # time.sleep(1)
+
def add_resource_mesh_callback(self, goal_handle : ServerGoalHandle):
tf_update_msg = goal_handle.request
@@ -147,7 +150,7 @@ class ResourceMeshManager(BaseROS2DeviceNode):
"""刷新资源配置"""
registry = lab_registry
- resource_config = json.loads(resource_config_str)
+ resource_config = json.loads(resource_config_str.replace("'",'"'))
if resource_config['id'] in self.resource_config_dict:
self.get_logger().info(f'资源 {resource_config["id"]} 已存在')
@@ -158,7 +161,7 @@ class ResourceMeshManager(BaseROS2DeviceNode):
self.resource_model[resource_config['id']] = {
'mesh': f"{str(self.mesh_path)}/device_mesh/resources/{model_config['mesh']}",
'mesh_tf': model_config['mesh_tf']}
- if model_config['children_mesh'] is not None:
+ if 'children_mesh' in model_config.keys():
self.resource_model[f"{resource_config['id']}_"] = {
'mesh': f"{str(self.mesh_path)}/device_mesh/resources/{model_config['children_mesh']}",
'mesh_tf': model_config['children_mesh_tf']
@@ -187,7 +190,8 @@ class ResourceMeshManager(BaseROS2DeviceNode):
pass
elif parent is not None and resource_id in self.resource_model:
- parent_link = f"{self.resource_config_dict[parent]['parent']}_{parent}_device_link".replace("None","")
+ # parent_link = f"{self.resource_config_dict[parent]['parent']}_{parent}_device_link".replace("None_","")
+ parent_link = f"{parent}_device_link".replace("None_","")
else:
@@ -297,7 +301,7 @@ class ResourceMeshManager(BaseROS2DeviceNode):
"world",
resource_id,
rclpy.time.Time(seconds=0),
- rclpy.duration.Duration(seconds=5)
+ # rclpy.duration.Duration(seconds=5)
)
# 提取当前位姿信息
@@ -344,9 +348,7 @@ class ResourceMeshManager(BaseROS2DeviceNode):
self.resource_pose_publisher.publish(changed_poses_msg)
self.zero_count += 1
-
-
-
+
def _is_pose_equal(self, pose1, pose2, tolerance=1e-7):
"""
比较两个位姿是否相等(考虑浮点数精度)
@@ -386,14 +388,24 @@ class ResourceMeshManager(BaseROS2DeviceNode):
self.__planning_scene = self._get_planning_scene_service.call(
GetPlanningScene.Request()
).scene
-
- for resource_id, target_parent in cmd_dict.items():
+ self.__planning_scene.is_diff = True
+ planning_scene = PlanningScene()
+ planning_scene.is_diff = True
+ planning_scene.robot_state.is_diff = True
+ # time_start = self.get_clock().now()
+ time_start = rclpy.time.Time(seconds=0)
+ count = 0
+ for resource_id, target_parent in cmd_dict.items():
+ parent_id = target_parent
+ if target_parent == '__trash':
+ parent_id = 'world'
# 获取从resource_id到target_parent的转换
transform = self.tf_buffer.lookup_transform(
- target_parent,
+ parent_id,
resource_id,
- rclpy.time.Time(seconds=0)
+ time_start,
+ timeout=rclpy.duration.Duration(seconds=10)
)
# 提取转换中的位置和旋转信息
@@ -411,26 +423,62 @@ class ResourceMeshManager(BaseROS2DeviceNode):
}
self.resource_tf_dict[resource_id] = {
- "parent": target_parent,
+ "parent": parent_id,
"position": position,
"rotation": rotation
}
+
# self.attach_collision_object(id=resource_id,link_name=target_parent)
- collision_object = AttachedCollisionObject(
+ # time.sleep(0.02)
+ operation_attach = CollisionObject.ADD
+ operation_world = CollisionObject.REMOVE
+ if target_parent == 'world':
+ operation_attach = CollisionObject.REMOVE
+ operation_world = CollisionObject.ADD
+ elif target_parent == '__trash':
+ operation_attach = CollisionObject.REMOVE
+
+ world_object = CollisionObject(
id=resource_id,
- link_name=target_parent,
+ operation=operation_world
+ )
+ if target_parent != '__trash':
+ planning_scene.world.collision_objects.append(world_object)
+
+
+ collision_object = AttachedCollisionObject(
object=CollisionObject(
id=resource_id,
- operation=CollisionObject.ADD
+ operation=operation_attach
)
)
-
- self.__planning_scene.robot_state.attached_collision_objects.append(collision_object)
+ if target_parent != 'world' and target_parent != '__trash':
+ collision_object.link_name = target_parent
+ planning_scene.robot_state.attached_collision_objects.append(collision_object)
+
+ count += 1
+
+ if count > 30:
+ req = ApplyPlanningScene.Request()
+ req.scene = planning_scene
+ self.publish_resource_tf()
+ self._apply_planning_scene_service.call(req)
+ self.__planning_scene_publisher.publish(planning_scene)
+ count = 0
+
+ planning_scene = PlanningScene()
+ planning_scene.is_diff = True
+ planning_scene.robot_state.is_diff = True
+
req = ApplyPlanningScene.Request()
- req.scene = self.__planning_scene
- self._apply_planning_scene_service.call_async(req)
+ req.scene = planning_scene
self.publish_resource_tf()
+ self._apply_planning_scene_service.call(req)
+ self.__planning_scene_publisher.publish(planning_scene)
+
+ # self.__collision_object_publisher.publish(CollisionObject())
+
except Exception as e:
self.get_logger().error(f"更新资源TF字典失败: {e}")
@@ -440,18 +488,22 @@ class ResourceMeshManager(BaseROS2DeviceNode):
return SendCmd.Result(success=True)
+
def add_resource_collision_meshes(self,resource_tf_dict:dict):
"""
遍历资源配置字典,为每个在resource_model中有对应模型的资源添加碰撞网格
该方法检查每个资源ID是否在self.resource_model中有对应的3D模型文件路径,
- 如果有,则调用add_collision_mesh方法将其添加到碰撞环境中。
+
"""
self.get_logger().info('开始添加资源碰撞网格')
self.__planning_scene = self._get_planning_scene_service.call(
GetPlanningScene.Request()
).scene
+ planning_scene = PlanningScene()
+ planning_scene.is_diff = True
+ count = 0
for resource_id, tf_info in resource_tf_dict.items():
if resource_id in self.resource_model:
@@ -479,7 +531,8 @@ class ResourceMeshManager(BaseROS2DeviceNode):
quat_xyzw=q,
frame_id=resource_id
)
- self.__planning_scene.world.collision_objects.append(collision_object)
+ count += 1
+ planning_scene.world.collision_objects.append(collision_object)
elif f"{tf_info['parent']}_" in self.resource_model:
# 获取资源的父级框架ID
id_ = f"{tf_info['parent']}_"
@@ -507,14 +560,26 @@ class ResourceMeshManager(BaseROS2DeviceNode):
quat_xyzw=q,
frame_id=resource_id
)
+ count += 1
+ planning_scene.world.collision_objects.append(collision_object)
- self.__planning_scene.world.collision_objects.append(collision_object)
+ if count > 30:
+ req = ApplyPlanningScene.Request()
+ req.scene = planning_scene
+ self.publish_resource_tf()
+ self._apply_planning_scene_service.call(req)
+ self.__planning_scene_publisher.publish(planning_scene)
+ count = 0
+
+ planning_scene = PlanningScene()
+ planning_scene.is_diff = True
req = ApplyPlanningScene.Request()
- req.scene = self.__planning_scene
- self._apply_planning_scene_service.call_async(req)
-
-
+ req.scene = planning_scene
+ self.publish_resource_tf()
+ self._apply_planning_scene_service.call(req)
+ self.__planning_scene_publisher.publish(planning_scene)
+
self.get_logger().info('资源碰撞网格添加完成')
@@ -959,9 +1024,6 @@ class ResourceMeshManager(BaseROS2DeviceNode):
Attach collision object to the robot.
"""
- if link_name is None:
- link_name = self.__end_effector_name
-
msg = AttachedCollisionObject(
object=CollisionObject(id=id, operation=CollisionObject.ADD)
)
diff --git a/unilabos/ros/nodes/resource_tracker.py b/unilabos/ros/nodes/resource_tracker.py
index 04b5437..ff1a779 100644
--- a/unilabos/ros/nodes/resource_tracker.py
+++ b/unilabos/ros/nodes/resource_tracker.py
@@ -1,3 +1,5 @@
+from typing import List, Tuple, Any
+
from unilabos.utils.log import logger
@@ -5,12 +7,12 @@ class DeviceNodeResourceTracker(object):
def __init__(self):
self.resources = []
- self.root_resource2resource = {}
+ self.resource2parent_resource = {}
pass
- def root_resource(self, resource):
- if id(resource) in self.root_resource2resource:
- return self.root_resource2resource[id(resource)]
+ def parent_resource(self, resource):
+ if id(resource) in self.resource2parent_resource:
+ return self.resource2parent_resource[id(resource)]
else:
return resource
@@ -44,20 +46,21 @@ class DeviceNodeResourceTracker(object):
self.loop_find_resource(r, resource_cls_type, identifier_key, getattr(query_resource, identifier_key))
)
assert len(res_list) == 1, f"{query_resource} 找到多个资源,请检查资源是否唯一: {res_list}"
- self.root_resource2resource[id(query_resource)] = res_list[0]
+ self.resource2parent_resource[id(query_resource)] = res_list[0][0]
+ self.resource2parent_resource[id(res_list[0][1])] = res_list[0][0]
# 后续加入其他对比方式
- return res_list[0]
+ return res_list[0][1]
- def loop_find_resource(self, resource, target_resource_cls_type, identifier_key, compare_value):
+ def loop_find_resource(self, resource, target_resource_cls_type, identifier_key, compare_value, parent_res=None) -> List[Tuple[Any, Any]]:
res_list = []
# print(resource, target_resource_cls_type, identifier_key, compare_value)
children = getattr(resource, "children", [])
for child in children:
- res_list.extend(self.loop_find_resource(child, target_resource_cls_type, identifier_key, compare_value))
+ res_list.extend(self.loop_find_resource(child, target_resource_cls_type, identifier_key, compare_value, resource))
if target_resource_cls_type == type(resource) or target_resource_cls_type == dict:
if hasattr(resource, identifier_key):
if getattr(resource, identifier_key) == compare_value:
- res_list.append(resource)
+ res_list.append((parent_res, resource))
return res_list
def filter_find_list(self, res_list, compare_std_dict):
diff --git a/unilabos/ros/utils/driver_creator.py b/unilabos/ros/utils/driver_creator.py
index 1218725..9f223f9 100644
--- a/unilabos/ros/utils/driver_creator.py
+++ b/unilabos/ros/utils/driver_creator.py
@@ -105,40 +105,41 @@ class PyLabRobotCreator(DeviceClassCreator[T]):
return nested_dict_to_list(resource), Resource
return resource, source_type
- def _process_resource_references(self, data: Any, to_dict=False) -> Any:
+ def _process_resource_references(self, data: Any, to_dict=False, states=None, prefix_path="") -> Any:
"""
递归处理资源引用,替换_resource_child_name对应的资源
Args:
data: 需要处理的数据,可能是字典、列表或其他类型
- to_dict: 转换成对应的实例,还是转换成对应的字典
+ to_dict: 是否返回字典形式的资源
+ states: 用于保存所有资源状态
+ prefix_path: 当前递归路径
Returns:
处理后的数据
"""
from pylabrobot.resources import Deck, Resource
+ if states is None:
+ states = {}
if isinstance(data, dict):
- # 检查是否包含资源引用
if "_resource_child_name" in data:
child_name = data["_resource_child_name"]
if child_name in self.children:
- # 找到了对应的资源
resource = self.children[child_name]
-
- # 检查是否需要转换资源类型
if "_resource_type" in data:
type_path = data["_resource_type"]
try:
- # 尝试导入指定的类型
target_type = import_manager.get_class(type_path)
contain_model = not issubclass(target_type, Deck)
resource, target_type = self._process_resource_mapping(resource, target_type)
- # 在截图中格式,是deserialize,所以这里要转成plr resource可deserialize的字典
- # 这样后面执行deserialize的时候能够正确反序列化对应的物料
resource_instance: Resource = resource_ulab_to_plr(resource, contain_model)
+
+ # 使用 prefix_path 作为 key 存储资源状态
if to_dict:
- return resource_instance.serialize()
+ serialized = resource_instance.serialize()
+ states[prefix_path] = resource_instance.serialize_all_state()
+ return serialized
else:
self.resource_tracker.add_resource(resource_instance)
return resource_instance
@@ -151,18 +152,21 @@ class PyLabRobotCreator(DeviceClassCreator[T]):
else:
logger.warning(f"找不到资源引用 '{child_name}',保持原值不变")
- # 递归处理字典的每个值
+ # 递归处理每个键值
result = {}
for key, value in data.items():
- result[key] = self._process_resource_references(value, to_dict)
+ new_prefix = f"{prefix_path}.{key}" if prefix_path else key
+ result[key] = self._process_resource_references(value, to_dict, states, new_prefix)
return result
- # 处理列表类型
elif isinstance(data, list):
- return [self._process_resource_references(item, to_dict) for item in data]
+ return [
+ self._process_resource_references(item, to_dict, states, f"{prefix_path}[{i}]")
+ for i, item in enumerate(data)
+ ]
- # 其他类型直接返回
- return data
+ else:
+ return data
def create_instance(self, data: Dict[str, Any]) -> Optional[T]:
"""
@@ -187,10 +191,18 @@ class PyLabRobotCreator(DeviceClassCreator[T]):
logger.debug(f"自动补充 _resource_type: {data[param_name]['_resource_type']}")
# 首先处理资源引用
- processed_data = self._process_resource_references(data, to_dict=True)
+ states = {}
+ processed_data = self._process_resource_references(data, to_dict=True, states=states)
try:
self.device_instance = deserialize_method(**processed_data)
+ all_states = self.device_instance.serialize_all_state()
+ for k, v in states.items():
+ logger.debug(f"PyLabRobot反序列化设置状态:{k}")
+ for kk, vv in all_states.items():
+ if kk not in v:
+ v[kk] = vv
+ self.device_instance.deck.load_all_state(v)
self.resource_tracker.add_resource(self.device_instance)
self.post_create()
return self.device_instance # type: ignore
@@ -225,6 +237,10 @@ class PyLabRobotCreator(DeviceClassCreator[T]):
if hasattr(self.device_instance, "setup") and asyncio.iscoroutinefunction(getattr(self.device_instance, "setup")):
from unilabos.ros.nodes.base_device_node import ROS2DeviceNode
def done_cb(*args):
+ from pylabrobot.resources import set_volume_tracking
+ # from pylabrobot.resources import set_tip_tracking
+ set_volume_tracking(enabled=True)
+ # set_tip_tracking(enabled=True) # 序列化tip_spot has为False
logger.debug(f"PyLabRobot设备实例 {self.device_instance} 设置完成")
from unilabos.config.config import BasicConfig
if BasicConfig.vis_2d_enable:
diff --git a/unilabos_msgs/action/LiquidHandlerMoveBiomek.action b/unilabos_msgs/action/LiquidHandlerMoveBiomek.action
index b12feb1..9c75206 100644
--- a/unilabos_msgs/action/LiquidHandlerMoveBiomek.action
+++ b/unilabos_msgs/action/LiquidHandlerMoveBiomek.action
@@ -1,5 +1,5 @@
-string source
-string target
+string sources
+string targets
---
string return_info
diff --git a/unilabos_msgs/action/LiquidHandlerTransferBiomek.action b/unilabos_msgs/action/LiquidHandlerTransferBiomek.action
index cee47bc..65db264 100644
--- a/unilabos_msgs/action/LiquidHandlerTransferBiomek.action
+++ b/unilabos_msgs/action/LiquidHandlerTransferBiomek.action
@@ -1,5 +1,5 @@
-string source
-string target
+string sources
+string targets
string tip_rack
float64 volume
string aspirate_technique