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