Files
Uni-Lab-OS/unilabos/devices/liquid_handling/biomek.py
Xuwznln aa1c67de29 Device Visualization & Mock Devices (#44) [37-biomek-i5i7 (#40), Device visualization (#39), Add Mock Device for Organic Synthesis\添加有机合成的虚拟仪器和Protocol (#43)]
* add biomek.py demo implementation

* 更新LiquidHandlerBiomek类,添加资源创建功能,优化协议创建方法,修复部分代码格式问题,更新YAML配置以支持新功能。

* Test

* fix biomek success type

* Convert LH action to biomek.

* Update biomek.py

* 注册表上报handle和schema (param input)

* 修复biomek缺少的字段

* delete 's'

* Remove warnings

* Update biomek.py

* Biomek test

* Update biomek.py

* 新增transfer_biomek的msg

* New transfer_biomek

* Updated transfer_biomek

* 更新transfer_biomek的msg

* 更新transfer_biomek的msg

* 支持Biomek创建

* new action

* fix key name typo

* New parameter for biomek to run.

* Refine

* Update

* new actions

* new actions

* 1

* registry

* fix biomek startup
add action handles

* fix handles not as default entry

* biomek_test.py

biomek_test.py是最新的版本,运行它会生成complete_biomek_protocol.json

* Update biomek.py

* biomek_test.py

* fix liquid_handler.biomek handles

* host node新增resource add时间统计
create_resource新增handle
bump version to 0.9.2

* 修正物料上传时间
改用biomek_test
增加ResultInfoEncoder
支持返回结果上传

* 正确发送return_info结果

* 同步执行状态信息

* 取消raiseValueError提示

* Update biomek_test.py

* 0608 DONE

* 同步了Biomek.py 现在应可用

* biomek switch back to non-test

* temp disable initialize resource

* 37-biomek-i5i7 (#40)

* add biomek.py demo implementation

* 更新LiquidHandlerBiomek类,添加资源创建功能,优化协议创建方法,修复部分代码格式问题,更新YAML配置以支持新功能。

* Test

* fix biomek success type

* Convert LH action to biomek.

* Update biomek.py

* 注册表上报handle和schema (param input)

* 修复biomek缺少的字段

* delete 's'

* Remove warnings

* Update biomek.py

* Biomek test

* Update biomek.py

* 新增transfer_biomek的msg

* New transfer_biomek

* Updated transfer_biomek

* 更新transfer_biomek的msg

* 更新transfer_biomek的msg

* 支持Biomek创建

* new action

* fix key name typo

* New parameter for biomek to run.

* Refine

* Update

* new actions

* new actions

* 1

* registry

* fix biomek startup
add action handles

* fix handles not as default entry

* biomek_test.py

biomek_test.py是最新的版本,运行它会生成complete_biomek_protocol.json

* Update biomek.py

* biomek_test.py

* fix liquid_handler.biomek handles

* host node新增resource add时间统计
create_resource新增handle
bump version to 0.9.2

* 修正物料上传时间
改用biomek_test
增加ResultInfoEncoder
支持返回结果上传

* 正确发送return_info结果

* 同步执行状态信息

* 取消raiseValueError提示

* Update biomek_test.py

* 0608 DONE

* 同步了Biomek.py 现在应可用

* biomek switch back to non-test

* temp disable initialize resource

* Refine biomek

* Refine copy issue

* Refine

---------

Co-authored-by: Junhan Chang <changjh@pku.edu.cn>
Co-authored-by: Guangxin Zhang <guangxin.zhang.bio@gmail.com>
Co-authored-by: qxw138 <qxw@stu.pku.edu.cn>

* Device visualization (#39)

* Update README and MQTTClient for installation instructions and code improvements

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

* add: registry description

* add 3d visualization

* 完成在main中启动设备可视化

完成在main中启动设备可视化,并输出物料ID:mesh的对应关系resource_model

添加物料模型管理类,遍历物料与resource_model,完成TF数据收集

* 完成TF发布

* 修改模型方向,在yaml中添加变换属性

* 添加物料tf变化时,发送topic到前端

另外修改了物料初始化的方法,防止在tf还未发布时提前建立物料模型与发布话题

* 添加关节发布节点与物料可视化节点进入unilab

* 使用json启动plr与3D模型仿真

* feat: node_info_update srv
fix: OTDeck cant create

* close #12
feat: slave node registry

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

* feat: add hplc registry

* feat: add hplc registry

* fix: hplc status typo

* fix: devices/

* 完成启动OT并联动rviz

* add 3d visualization

* 完成在main中启动设备可视化

完成在main中启动设备可视化,并输出物料ID:mesh的对应关系resource_model

添加物料模型管理类,遍历物料与resource_model,完成TF数据收集

* 完成TF发布

* 修改模型方向,在yaml中添加变换属性

* 添加物料tf变化时,发送topic到前端

另外修改了物料初始化的方法,防止在tf还未发布时提前建立物料模型与发布话题

* 添加关节发布节点与物料可视化节点进入unilab

* 使用json启动plr与3D模型仿真

* 完成启动OT并联动rviz

* fix: device.class possible null

* fix: HPLC additions with online service

* fix: slave mode spin not working

* fix: slave mode spin not working

* 修复rviz位置问题,

修复rviz位置问题,
在无tf变动时减缓发送频率
在backend中添加物料跟随方法

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

* feat: 支持env设置config

* fix: running logic

* fix: running logic

* fix: missing ot

* 在main中直接初始化republisher和物料的mesh节点

* 将joint_republisher和resource_mesh_manager添加进 main_slave_run.py中

* Device visualization (#14)

* add 3d visualization

* 完成在main中启动设备可视化

完成在main中启动设备可视化,并输出物料ID:mesh的对应关系resource_model

添加物料模型管理类,遍历物料与resource_model,完成TF数据收集

* 完成TF发布

* 修改模型方向,在yaml中添加变换属性

* 添加物料tf变化时,发送topic到前端

另外修改了物料初始化的方法,防止在tf还未发布时提前建立物料模型与发布话题

* 添加关节发布节点与物料可视化节点进入unilab

* 使用json启动plr与3D模型仿真

* 完成启动OT并联动rviz

* add 3d visualization

* 完成在main中启动设备可视化

完成在main中启动设备可视化,并输出物料ID:mesh的对应关系resource_model

添加物料模型管理类,遍历物料与resource_model,完成TF数据收集

* 完成TF发布

* 修改模型方向,在yaml中添加变换属性

* 添加物料tf变化时,发送topic到前端

另外修改了物料初始化的方法,防止在tf还未发布时提前建立物料模型与发布话题

* 添加关节发布节点与物料可视化节点进入unilab

* 使用json启动plr与3D模型仿真

* 完成启动OT并联动rviz

* 修复rviz位置问题,

修复rviz位置问题,
在无tf变动时减缓发送频率
在backend中添加物料跟随方法

* fix: running logic

* fix: running logic

* fix: missing ot

* 在main中直接初始化republisher和物料的mesh节点

* 将joint_republisher和resource_mesh_manager添加进 main_slave_run.py中

---------

Co-authored-by: zhangshixiang <@zhangshixiang>
Co-authored-by: wznln <18435084+Xuwznln@users.noreply.github.com>

* fix: missing hostname in devices_names
fix: upload_file for model file

* fix: missing paho-mqtt package
bump version to 0.9.0

* fix startup
add ResourceCreateFromOuter.action

* fix type hint

* update actions

* update actions

* host node add_resource_from_outer
fix cmake list

* pass device config to device class

* add: bind_parent_ids to resource create action
fix: message convert string

* fix: host node should not be re_discovered

* feat: resource tracker support dict

* feat: add more necessary params

* feat: fix boolean null in registry action data

* feat: add outer resource

* 编写mesh添加action

* feat: append resource

* add action

* feat: vis 2d for plr

* fix

* fix: browser on rviz

* fix: cloud bridge error fallback to local

* fix: salve auto run rviz

* 初始化两个plate

* Device visualization (#22)

* add 3d visualization

* 完成在main中启动设备可视化

完成在main中启动设备可视化,并输出物料ID:mesh的对应关系resource_model

添加物料模型管理类,遍历物料与resource_model,完成TF数据收集

* 完成TF发布

* 修改模型方向,在yaml中添加变换属性

* 添加物料tf变化时,发送topic到前端

另外修改了物料初始化的方法,防止在tf还未发布时提前建立物料模型与发布话题

* 添加关节发布节点与物料可视化节点进入unilab

* 使用json启动plr与3D模型仿真

* 完成启动OT并联动rviz

* add 3d visualization

* 完成在main中启动设备可视化

完成在main中启动设备可视化,并输出物料ID:mesh的对应关系resource_model

添加物料模型管理类,遍历物料与resource_model,完成TF数据收集

* 完成TF发布

* 修改模型方向,在yaml中添加变换属性

* 添加物料tf变化时,发送topic到前端

另外修改了物料初始化的方法,防止在tf还未发布时提前建立物料模型与发布话题

* 添加关节发布节点与物料可视化节点进入unilab

* 使用json启动plr与3D模型仿真

* 完成启动OT并联动rviz

* 修复rviz位置问题,

修复rviz位置问题,
在无tf变动时减缓发送频率
在backend中添加物料跟随方法

* fix: running logic

* fix: running logic

* fix: missing ot

* 在main中直接初始化republisher和物料的mesh节点

* 将joint_republisher和resource_mesh_manager添加进 main_slave_run.py中

* 编写mesh添加action

* add action

* fix

* fix: browser on rviz

* fix: cloud bridge error fallback to local

* fix: salve auto run rviz

* 初始化两个plate

---------

Co-authored-by: zhangshixiang <@zhangshixiang>
Co-authored-by: wznln <18435084+Xuwznln@users.noreply.github.com>

* fix: multi channel

* fix: aspirate

* fix: aspirate

* fix: aspirate

* fix: aspirate

* 提交

* fix: jobadd

* fix: jobadd

* fix: msg converter

* tijiao

* add resource creat easy action

* identify debug msg

* mq client id

* 提取lh的joint发布

* unify liquid_handler definition

* 修改物料跟随与物料添加逻辑

修改物料跟随与物料添加逻辑
将joint_publisher类移出lh的backends,但仍需要对lh的backends进行一些改写

* Revert "修改物料跟随与物料添加逻辑"

This reverts commit 498c997ad7.

* Reapply "修改物料跟随与物料添加逻辑"

This reverts commit 3a60d2ae81.

* Revert "Merge remote-tracking branch 'upstream/dev' into device_visualization"

This reverts commit fa727220af, reversing
changes made to 498c997ad7.

* 修改物料放下时的方法,如果选择

修改物料放下时的方法,
如果选择drop_trash,则删除物料显示
如果选择drop,则让其解除连接

* add biomek.py demo implementation

* 更新LiquidHandlerBiomek类,添加资源创建功能,优化协议创建方法,修复部分代码格式问题,更新YAML配置以支持新功能。

* Test

* fix biomek success type

* Convert LH action to biomek.

* Update biomek.py

* 注册表上报handle和schema (param input)

* 修复biomek缺少的字段

* delete 's'

* Remove warnings

* Update biomek.py

* Biomek test

* Update biomek.py

* 新增transfer_biomek的msg

* New transfer_biomek

* Updated transfer_biomek

* 更新transfer_biomek的msg

* 更新transfer_biomek的msg

* 支持Biomek创建

* new action

* fix key name typo

* New parameter for biomek to run.

* Refine

* Update

* new actions

* new actions

* 1

* registry

* fix biomek startup
add action handles

* fix handles not as default entry

* unilab添加moveit启动

1,整合所有moveit节点到一个move_group中,并整合所有的controller依次激活
2,添加pymoveit2的节点,使用json可直接启动
3,修改机械臂规划方式,添加约束,让冗余关节不会进行过多移动

* biomek_test.py

biomek_test.py是最新的版本,运行它会生成complete_biomek_protocol.json

* Update biomek.py

* biomek_test.py

* fix liquid_handler.biomek handles

* 修改物体attach时,多次赋值当前时间导致卡顿问题,

* Revert "修改物体attach时,多次赋值当前时间导致卡顿问题,"

This reverts commit 56d45b94f5.

* Reapply "修改物体attach时,多次赋值当前时间导致卡顿问题,"

This reverts commit 07d9db20c3.

* 添加缺少物料:"plate_well_G12",

* host node新增resource add时间统计
create_resource新增handle
bump version to 0.9.2

* 修正物料上传时间
改用biomek_test
增加ResultInfoEncoder
支持返回结果上传

* 正确发送return_info结果

* 同步执行状态信息

* 取消raiseValueError提示

* Update biomek_test.py

* 0608 DONE

* 同步了Biomek.py 现在应可用

* biomek switch back to non-test

* temp disable initialize resource

* add

* fix tip resource data

* liquid states

* change to debug level

* Revert "change to debug level"

This reverts commit 5d9953c3e5.

* Reapply "change to debug level"

This reverts commit 2487bb6ffc.

* fix tip resource data

* add full device

* add moveit yaml

* 修复moveit
增加post_init阶段,给予ros_node反向

* remove necessary node

* fix moveit action client

* remove necessary imports

* Update moveit_interface.py

* fix handler_key uppercase

* json add liquids

* fix setup

* add

* change to "sources" and "targets" for lh

* bump version

* remove parent's parent link

---------

Co-authored-by: Harvey Que <Q-Query@outlook.com>
Co-authored-by: wznln <18435084+Xuwznln@users.noreply.github.com>
Co-authored-by: zhangshixiang <@zhangshixiang>
Co-authored-by: Junhan Chang <changjh@pku.edu.cn>
Co-authored-by: Guangxin Zhang <guangxin.zhang.bio@gmail.com>
Co-authored-by: qxw138 <qxw@stu.pku.edu.cn>

* Device visualization (#41)

* Update README and MQTTClient for installation instructions and code improvements

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

* add: registry description

* add 3d visualization

* 完成在main中启动设备可视化

完成在main中启动设备可视化,并输出物料ID:mesh的对应关系resource_model

添加物料模型管理类,遍历物料与resource_model,完成TF数据收集

* 完成TF发布

* 修改模型方向,在yaml中添加变换属性

* 添加物料tf变化时,发送topic到前端

另外修改了物料初始化的方法,防止在tf还未发布时提前建立物料模型与发布话题

* 添加关节发布节点与物料可视化节点进入unilab

* 使用json启动plr与3D模型仿真

* feat: node_info_update srv
fix: OTDeck cant create

* close #12
feat: slave node registry

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

* feat: add hplc registry

* feat: add hplc registry

* fix: hplc status typo

* fix: devices/

* 完成启动OT并联动rviz

* add 3d visualization

* 完成在main中启动设备可视化

完成在main中启动设备可视化,并输出物料ID:mesh的对应关系resource_model

添加物料模型管理类,遍历物料与resource_model,完成TF数据收集

* 完成TF发布

* 修改模型方向,在yaml中添加变换属性

* 添加物料tf变化时,发送topic到前端

另外修改了物料初始化的方法,防止在tf还未发布时提前建立物料模型与发布话题

* 添加关节发布节点与物料可视化节点进入unilab

* 使用json启动plr与3D模型仿真

* 完成启动OT并联动rviz

* fix: device.class possible null

* fix: HPLC additions with online service

* fix: slave mode spin not working

* fix: slave mode spin not working

* 修复rviz位置问题,

修复rviz位置问题,
在无tf变动时减缓发送频率
在backend中添加物料跟随方法

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

* feat: 支持env设置config

* fix: running logic

* fix: running logic

* fix: missing ot

* 在main中直接初始化republisher和物料的mesh节点

* 将joint_republisher和resource_mesh_manager添加进 main_slave_run.py中

* Device visualization (#14)

* add 3d visualization

* 完成在main中启动设备可视化

完成在main中启动设备可视化,并输出物料ID:mesh的对应关系resource_model

添加物料模型管理类,遍历物料与resource_model,完成TF数据收集

* 完成TF发布

* 修改模型方向,在yaml中添加变换属性

* 添加物料tf变化时,发送topic到前端

另外修改了物料初始化的方法,防止在tf还未发布时提前建立物料模型与发布话题

* 添加关节发布节点与物料可视化节点进入unilab

* 使用json启动plr与3D模型仿真

* 完成启动OT并联动rviz

* add 3d visualization

* 完成在main中启动设备可视化

完成在main中启动设备可视化,并输出物料ID:mesh的对应关系resource_model

添加物料模型管理类,遍历物料与resource_model,完成TF数据收集

* 完成TF发布

* 修改模型方向,在yaml中添加变换属性

* 添加物料tf变化时,发送topic到前端

另外修改了物料初始化的方法,防止在tf还未发布时提前建立物料模型与发布话题

* 添加关节发布节点与物料可视化节点进入unilab

* 使用json启动plr与3D模型仿真

* 完成启动OT并联动rviz

* 修复rviz位置问题,

修复rviz位置问题,
在无tf变动时减缓发送频率
在backend中添加物料跟随方法

* fix: running logic

* fix: running logic

* fix: missing ot

* 在main中直接初始化republisher和物料的mesh节点

* 将joint_republisher和resource_mesh_manager添加进 main_slave_run.py中

---------

Co-authored-by: zhangshixiang <@zhangshixiang>
Co-authored-by: wznln <18435084+Xuwznln@users.noreply.github.com>

* fix: missing hostname in devices_names
fix: upload_file for model file

* fix: missing paho-mqtt package
bump version to 0.9.0

* fix startup
add ResourceCreateFromOuter.action

* fix type hint

* update actions

* update actions

* host node add_resource_from_outer
fix cmake list

* pass device config to device class

* add: bind_parent_ids to resource create action
fix: message convert string

* fix: host node should not be re_discovered

* feat: resource tracker support dict

* feat: add more necessary params

* feat: fix boolean null in registry action data

* feat: add outer resource

* 编写mesh添加action

* feat: append resource

* add action

* feat: vis 2d for plr

* fix

* fix: browser on rviz

* fix: cloud bridge error fallback to local

* fix: salve auto run rviz

* 初始化两个plate

* Device visualization (#22)

* add 3d visualization

* 完成在main中启动设备可视化

完成在main中启动设备可视化,并输出物料ID:mesh的对应关系resource_model

添加物料模型管理类,遍历物料与resource_model,完成TF数据收集

* 完成TF发布

* 修改模型方向,在yaml中添加变换属性

* 添加物料tf变化时,发送topic到前端

另外修改了物料初始化的方法,防止在tf还未发布时提前建立物料模型与发布话题

* 添加关节发布节点与物料可视化节点进入unilab

* 使用json启动plr与3D模型仿真

* 完成启动OT并联动rviz

* add 3d visualization

* 完成在main中启动设备可视化

完成在main中启动设备可视化,并输出物料ID:mesh的对应关系resource_model

添加物料模型管理类,遍历物料与resource_model,完成TF数据收集

* 完成TF发布

* 修改模型方向,在yaml中添加变换属性

* 添加物料tf变化时,发送topic到前端

另外修改了物料初始化的方法,防止在tf还未发布时提前建立物料模型与发布话题

* 添加关节发布节点与物料可视化节点进入unilab

* 使用json启动plr与3D模型仿真

* 完成启动OT并联动rviz

* 修复rviz位置问题,

修复rviz位置问题,
在无tf变动时减缓发送频率
在backend中添加物料跟随方法

* fix: running logic

* fix: running logic

* fix: missing ot

* 在main中直接初始化republisher和物料的mesh节点

* 将joint_republisher和resource_mesh_manager添加进 main_slave_run.py中

* 编写mesh添加action

* add action

* fix

* fix: browser on rviz

* fix: cloud bridge error fallback to local

* fix: salve auto run rviz

* 初始化两个plate

---------

Co-authored-by: zhangshixiang <@zhangshixiang>
Co-authored-by: wznln <18435084+Xuwznln@users.noreply.github.com>

* fix: multi channel

* fix: aspirate

* fix: aspirate

* fix: aspirate

* fix: aspirate

* 提交

* fix: jobadd

* fix: jobadd

* fix: msg converter

* tijiao

* add resource creat easy action

* identify debug msg

* mq client id

* 提取lh的joint发布

* unify liquid_handler definition

* 修改物料跟随与物料添加逻辑

修改物料跟随与物料添加逻辑
将joint_publisher类移出lh的backends,但仍需要对lh的backends进行一些改写

* Revert "修改物料跟随与物料添加逻辑"

This reverts commit 498c997ad7.

* Reapply "修改物料跟随与物料添加逻辑"

This reverts commit 3a60d2ae81.

* Revert "Merge remote-tracking branch 'upstream/dev' into device_visualization"

This reverts commit fa727220af, reversing
changes made to 498c997ad7.

* 修改物料放下时的方法,如果选择

修改物料放下时的方法,
如果选择drop_trash,则删除物料显示
如果选择drop,则让其解除连接

* add biomek.py demo implementation

* 更新LiquidHandlerBiomek类,添加资源创建功能,优化协议创建方法,修复部分代码格式问题,更新YAML配置以支持新功能。

* Test

* fix biomek success type

* Convert LH action to biomek.

* Update biomek.py

* 注册表上报handle和schema (param input)

* 修复biomek缺少的字段

* delete 's'

* Remove warnings

* Update biomek.py

* Biomek test

* Update biomek.py

* 新增transfer_biomek的msg

* New transfer_biomek

* Updated transfer_biomek

* 更新transfer_biomek的msg

* 更新transfer_biomek的msg

* 支持Biomek创建

* new action

* fix key name typo

* New parameter for biomek to run.

* Refine

* Update

* new actions

* new actions

* 1

* registry

* fix biomek startup
add action handles

* fix handles not as default entry

* unilab添加moveit启动

1,整合所有moveit节点到一个move_group中,并整合所有的controller依次激活
2,添加pymoveit2的节点,使用json可直接启动
3,修改机械臂规划方式,添加约束,让冗余关节不会进行过多移动

* biomek_test.py

biomek_test.py是最新的版本,运行它会生成complete_biomek_protocol.json

* Update biomek.py

* biomek_test.py

* fix liquid_handler.biomek handles

* 修改物体attach时,多次赋值当前时间导致卡顿问题,

* Revert "修改物体attach时,多次赋值当前时间导致卡顿问题,"

This reverts commit 56d45b94f5.

* Reapply "修改物体attach时,多次赋值当前时间导致卡顿问题,"

This reverts commit 07d9db20c3.

* 添加缺少物料:"plate_well_G12",

* host node新增resource add时间统计
create_resource新增handle
bump version to 0.9.2

* 修正物料上传时间
改用biomek_test
增加ResultInfoEncoder
支持返回结果上传

* 正确发送return_info结果

* 同步执行状态信息

* 取消raiseValueError提示

* Update biomek_test.py

* 0608 DONE

* 同步了Biomek.py 现在应可用

* biomek switch back to non-test

* temp disable initialize resource

* add

* fix tip resource data

* liquid states

* change to debug level

* Revert "change to debug level"

This reverts commit 5d9953c3e5.

* Reapply "change to debug level"

This reverts commit 2487bb6ffc.

* fix tip resource data

* add full device

* add moveit yaml

* 修复moveit
增加post_init阶段,给予ros_node反向

* remove necessary node

* fix moveit action client

* remove necessary imports

* Update moveit_interface.py

* fix handler_key uppercase

* json add liquids

* fix setup

* add

* change to "sources" and "targets" for lh

* bump version

* remove parent's parent link

* change arm's name

* change name

---------

Co-authored-by: Harvey Que <Q-Query@outlook.com>
Co-authored-by: zhangshixiang <@zhangshixiang>
Co-authored-by: q434343 <73513873+q434343@users.noreply.github.com>
Co-authored-by: Junhan Chang <changjh@pku.edu.cn>
Co-authored-by: Guangxin Zhang <guangxin.zhang.bio@gmail.com>
Co-authored-by: qxw138 <qxw@stu.pku.edu.cn>

* fix move it

* fix move it

* create_resource

* bump ver
modify slot type

* 增加modbus支持
调整protocol node以更好支持多种类型的read和write

* 调整protocol node以更好支持多种类型的read和write

* 补充日志

* Device visualization (#42)

* Update README and MQTTClient for installation instructions and code improvements

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

* add: registry description

* add 3d visualization

* 完成在main中启动设备可视化

完成在main中启动设备可视化,并输出物料ID:mesh的对应关系resource_model

添加物料模型管理类,遍历物料与resource_model,完成TF数据收集

* 完成TF发布

* 修改模型方向,在yaml中添加变换属性

* 添加物料tf变化时,发送topic到前端

另外修改了物料初始化的方法,防止在tf还未发布时提前建立物料模型与发布话题

* 添加关节发布节点与物料可视化节点进入unilab

* 使用json启动plr与3D模型仿真

* feat: node_info_update srv
fix: OTDeck cant create

* close #12
feat: slave node registry

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

* feat: add hplc registry

* feat: add hplc registry

* fix: hplc status typo

* fix: devices/

* 完成启动OT并联动rviz

* add 3d visualization

* 完成在main中启动设备可视化

完成在main中启动设备可视化,并输出物料ID:mesh的对应关系resource_model

添加物料模型管理类,遍历物料与resource_model,完成TF数据收集

* 完成TF发布

* 修改模型方向,在yaml中添加变换属性

* 添加物料tf变化时,发送topic到前端

另外修改了物料初始化的方法,防止在tf还未发布时提前建立物料模型与发布话题

* 添加关节发布节点与物料可视化节点进入unilab

* 使用json启动plr与3D模型仿真

* 完成启动OT并联动rviz

* fix: device.class possible null

* fix: HPLC additions with online service

* fix: slave mode spin not working

* fix: slave mode spin not working

* 修复rviz位置问题,

修复rviz位置问题,
在无tf变动时减缓发送频率
在backend中添加物料跟随方法

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

* feat: 支持env设置config

* fix: running logic

* fix: running logic

* fix: missing ot

* 在main中直接初始化republisher和物料的mesh节点

* 将joint_republisher和resource_mesh_manager添加进 main_slave_run.py中

* Device visualization (#14)

* add 3d visualization

* 完成在main中启动设备可视化

完成在main中启动设备可视化,并输出物料ID:mesh的对应关系resource_model

添加物料模型管理类,遍历物料与resource_model,完成TF数据收集

* 完成TF发布

* 修改模型方向,在yaml中添加变换属性

* 添加物料tf变化时,发送topic到前端

另外修改了物料初始化的方法,防止在tf还未发布时提前建立物料模型与发布话题

* 添加关节发布节点与物料可视化节点进入unilab

* 使用json启动plr与3D模型仿真

* 完成启动OT并联动rviz

* add 3d visualization

* 完成在main中启动设备可视化

完成在main中启动设备可视化,并输出物料ID:mesh的对应关系resource_model

添加物料模型管理类,遍历物料与resource_model,完成TF数据收集

* 完成TF发布

* 修改模型方向,在yaml中添加变换属性

* 添加物料tf变化时,发送topic到前端

另外修改了物料初始化的方法,防止在tf还未发布时提前建立物料模型与发布话题

* 添加关节发布节点与物料可视化节点进入unilab

* 使用json启动plr与3D模型仿真

* 完成启动OT并联动rviz

* 修复rviz位置问题,

修复rviz位置问题,
在无tf变动时减缓发送频率
在backend中添加物料跟随方法

* fix: running logic

* fix: running logic

* fix: missing ot

* 在main中直接初始化republisher和物料的mesh节点

* 将joint_republisher和resource_mesh_manager添加进 main_slave_run.py中

---------

Co-authored-by: zhangshixiang <@zhangshixiang>
Co-authored-by: wznln <18435084+Xuwznln@users.noreply.github.com>

* fix: missing hostname in devices_names
fix: upload_file for model file

* fix: missing paho-mqtt package
bump version to 0.9.0

* fix startup
add ResourceCreateFromOuter.action

* fix type hint

* update actions

* update actions

* host node add_resource_from_outer
fix cmake list

* pass device config to device class

* add: bind_parent_ids to resource create action
fix: message convert string

* fix: host node should not be re_discovered

* feat: resource tracker support dict

* feat: add more necessary params

* feat: fix boolean null in registry action data

* feat: add outer resource

* 编写mesh添加action

* feat: append resource

* add action

* feat: vis 2d for plr

* fix

* fix: browser on rviz

* fix: cloud bridge error fallback to local

* fix: salve auto run rviz

* 初始化两个plate

* Device visualization (#22)

* add 3d visualization

* 完成在main中启动设备可视化

完成在main中启动设备可视化,并输出物料ID:mesh的对应关系resource_model

添加物料模型管理类,遍历物料与resource_model,完成TF数据收集

* 完成TF发布

* 修改模型方向,在yaml中添加变换属性

* 添加物料tf变化时,发送topic到前端

另外修改了物料初始化的方法,防止在tf还未发布时提前建立物料模型与发布话题

* 添加关节发布节点与物料可视化节点进入unilab

* 使用json启动plr与3D模型仿真

* 完成启动OT并联动rviz

* add 3d visualization

* 完成在main中启动设备可视化

完成在main中启动设备可视化,并输出物料ID:mesh的对应关系resource_model

添加物料模型管理类,遍历物料与resource_model,完成TF数据收集

* 完成TF发布

* 修改模型方向,在yaml中添加变换属性

* 添加物料tf变化时,发送topic到前端

另外修改了物料初始化的方法,防止在tf还未发布时提前建立物料模型与发布话题

* 添加关节发布节点与物料可视化节点进入unilab

* 使用json启动plr与3D模型仿真

* 完成启动OT并联动rviz

* 修复rviz位置问题,

修复rviz位置问题,
在无tf变动时减缓发送频率
在backend中添加物料跟随方法

* fix: running logic

* fix: running logic

* fix: missing ot

* 在main中直接初始化republisher和物料的mesh节点

* 将joint_republisher和resource_mesh_manager添加进 main_slave_run.py中

* 编写mesh添加action

* add action

* fix

* fix: browser on rviz

* fix: cloud bridge error fallback to local

* fix: salve auto run rviz

* 初始化两个plate

---------

Co-authored-by: zhangshixiang <@zhangshixiang>
Co-authored-by: wznln <18435084+Xuwznln@users.noreply.github.com>

* fix: multi channel

* fix: aspirate

* fix: aspirate

* fix: aspirate

* fix: aspirate

* 提交

* fix: jobadd

* fix: jobadd

* fix: msg converter

* tijiao

* add resource creat easy action

* identify debug msg

* mq client id

* 提取lh的joint发布

* unify liquid_handler definition

* 修改物料跟随与物料添加逻辑

修改物料跟随与物料添加逻辑
将joint_publisher类移出lh的backends,但仍需要对lh的backends进行一些改写

* Revert "修改物料跟随与物料添加逻辑"

This reverts commit 498c997ad7.

* Reapply "修改物料跟随与物料添加逻辑"

This reverts commit 3a60d2ae81.

* Revert "Merge remote-tracking branch 'upstream/dev' into device_visualization"

This reverts commit fa727220af, reversing
changes made to 498c997ad7.

* 修改物料放下时的方法,如果选择

修改物料放下时的方法,
如果选择drop_trash,则删除物料显示
如果选择drop,则让其解除连接

* unilab添加moveit启动

1,整合所有moveit节点到一个move_group中,并整合所有的controller依次激活
2,添加pymoveit2的节点,使用json可直接启动
3,修改机械臂规划方式,添加约束,让冗余关节不会进行过多移动

* 修改物体attach时,多次赋值当前时间导致卡顿问题,

* Revert "修改物体attach时,多次赋值当前时间导致卡顿问题,"

This reverts commit 56d45b94f5.

* Reapply "修改物体attach时,多次赋值当前时间导致卡顿问题,"

This reverts commit 07d9db20c3.

* 添加缺少物料:"plate_well_G12",

* add

* fix tip resource data

* liquid states

* change to debug level

* Revert "change to debug level"

This reverts commit 5d9953c3e5.

* Reapply "change to debug level"

This reverts commit 2487bb6ffc.

* fix tip resource data

* add full device

* add moveit yaml

* 修复moveit
增加post_init阶段,给予ros_node反向

* remove necessary node

* fix moveit action client

* remove necessary imports

* Update moveit_interface.py

* fix handler_key uppercase

* json add liquids

* fix setup

* add

* change to "sources" and "targets" for lh

* bump version

* remove parent's parent link

* change arm's name

* change name

* fix ik error

---------

Co-authored-by: Harvey Que <Q-Query@outlook.com>
Co-authored-by: zhangshixiang <@zhangshixiang>
Co-authored-by: q434343 <73513873+q434343@users.noreply.github.com>
Co-authored-by: Junhan Chang <changjh@pku.edu.cn>

* Add Mock Device for Organic Synthesis\添加有机合成的虚拟仪器和Protocol (#43)

* Add Device MockChiller

Add device MockChiller

* Add Device MockFilter

* Add Device MockPump

* Add Device MockRotavap

* Add Device MockSeparator

* Add Device MockStirrer

* Add Device MockHeater

* Add Device MockVacuum

* Add Device MockSolenoidValve

* Add Device Mock \_init_.py

* 规范模拟设备代码与注册表信息

* 更改Mock大写文件夹名

* 删除大写目录

* Edited Mock device json

* Match mock device with action

* Edit mock device yaml

* Add new action

* Add Virtual Device, Action, YAML, Protocol for Organic Syn

* 单独分类测试的protocol文件夹

* 更名Action

---------

Co-authored-by: Xuwznln <18435084+Xuwznln@users.noreply.github.com>

---------

Co-authored-by: Junhan Chang <changjh@pku.edu.cn>
Co-authored-by: Guangxin Zhang <guangxin.zhang.bio@gmail.com>
Co-authored-by: qxw138 <qxw@stu.pku.edu.cn>
Co-authored-by: q434343 <73513873+q434343@users.noreply.github.com>
Co-authored-by: Harvey Que <Q-Query@outlook.com>
Co-authored-by: Kongchang Feng <2100011801@stu.pku.edu.cn>
2025-06-12 21:01:04 +08:00

1099 lines
33 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import json
import pathlib
from typing import Sequence, Optional, List, Union, Literal
import requests
from geometry_msgs.msg import Point
from pylabrobot.liquid_handling import LiquidHandler
from pylabrobot.resources import (
TipRack,
Container,
Coordinate,
)
import copy
from unilabos_msgs.msg import Resource
from unilabos.ros.nodes.resource_tracker import DeviceNodeResourceTracker # type: ignore
class LiquidHandlerBiomek:
"""
Biomek液体处理器的实现类继承自LiquidHandlerAbstract。
该类用于处理Biomek液体处理器的特定操作。
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._status = "Idle" # 初始状态为 Idle
self._success = False # 初始成功状态为 False
self._status_queue = kwargs.get("status_queue", None) # 状态队列
self.temp_protocol = {}
self.py32_path = "/opt/py32" # Biomek的Python 3.2路径
# 预定义的仪器分类
self.tip_racks = [
"BC230", "BC1025F", "BC50", "TipRack200", "TipRack1000",
"tip", "tips", "Tip", "Tips"
]
self.reservoirs = [
"AgilentReservoir", "nest_12_reservoir_15ml", "nest_1_reservoir_195ml",
"reservoir", "Reservoir", "waste", "Waste"
]
self.plates_96 = [
"BCDeep96Round", "Matrix96_750uL", "NEST 2ml Deep Well Plate", "nest_96_wellplate_100ul_pcr_full_skirt",
"nest_96_wellplate_200ul_flat", "Matrix96", "96", "plate", "Plate"
]
self.aspirate_techniques = {
'MC P300 high':{
'Position': 'P1',
'Height': -2.0,
'Volume': '50',
'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, True),
'Prototype': 'MC P300 High',
'ReferencedPattern': '',
'RowsFirst': False,
'SectionExpression': '',
'SelectionInfo': (1,),
'SetMark': True,
'Source': True,
'StartAtMark': False,
'StartAtSelection': True,
'UseExpression': False},
}
self.dispense_techniques = {
'MC P300 high':{
'Position': 'P11',
'Height': -2.0,
'Volume': '50',
'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}
}
def _get_instrument_type(self, class_name: str) -> str:
"""
根据class_name判断仪器类型
Returns:
str: "tip_rack", "reservoir", "plate_96", 或 "unknown"
"""
# 检查是否是枪头架
for tip_name in self.tip_racks:
if tip_name in class_name:
return "tip_rack"
# 检查是否是储液槽
for reservoir_name in self.reservoirs:
if reservoir_name in class_name:
return "reservoir"
# 检查是否是96孔板
for plate_name in self.plates_96:
if plate_name in class_name:
return "plate_96"
return "unknown"
@classmethod
def deserialize(cls, data: dict, allow_marshal: bool = False) -> LiquidHandler:
return LiquidHandler.deserialize(data, allow_marshal)
@property
def success(self):
"""
获取操作是否成功的状态。
Returns:
bool: 如果操作成功返回True否则返回False。
"""
return self._success
def create_protocol(
self,
protocol_name: str,
protocol_description: str,
protocol_version: str,
protocol_author: str,
protocol_date: str,
protocol_type: str,
none_keys: List[str] = [],
):
"""
创建一个新的协议。
Args:
protocol_name (str): 协议名称
protocol_description (str): 协议描述
protocol_version (str): 协议版本
protocol_author (str): 协议作者
protocol_date (str): 协议日期
protocol_type (str): 协议类型
none_keys (List[str]): 需要设置为None的键列表
Returns:
dict: 创建的协议字典
"""
self.temp_protocol = {
"meta": {
"name": protocol_name,
"description": protocol_description,
"version": protocol_version,
"author": protocol_author,
"date": protocol_date,
"type": protocol_type,
},
"labwares": {},
"steps": [],
}
return self.temp_protocol
def run_protocol(self):
"""
执行创建的实验流程。
工作站的完整执行流程是,
从 create_protocol 开始,创建新的 method
随后执行 transfer_liquid 等操作向实验流程添加步骤,
最后 run_protocol 执行整个方法。
Returns:
dict: 执行结果
"""
#use popen or subprocess to create py32 process and communicate send the temp protocol to it
if not self.temp_protocol:
raise ValueError("No protocol created. Please create a protocol first.")
# 模拟执行协议
self._status = "Running"
self._success = True
# 在这里可以添加实际执行协议的逻辑
response = requests.post("localhost:5000/api/protocols", json=self.temp_protocol)
def create_resource(
self,
resource_tracker: DeviceNodeResourceTracker,
resources: list[Resource],
bind_parent_id: str,
bind_location: dict[str, float],
liquid_input_slot: list[int],
liquid_type: list[str],
liquid_volume: list[int],
slot_on_deck: int,
):
"""
创建一个新的资源。
Args:
device_id (str): 设备ID
res_id (str): 资源ID
class_name (str): 资源类名
parent (str): 父级ID
bind_locations (Point): 绑定位置
liquid_input_slot (list[int]): 液体输入槽列表
liquid_type (list[str]): 液体类型列表
liquid_volume (list[int]): 液体体积列表
slot_on_deck (int): 甲板上的槽位
Returns:
dict: 创建的资源字典
"""
# TODO需要对好接口下面这个是临时的
for resource in resources:
res_id = resource.id
class_name = resource.name
parent = bind_parent_id
liquid_input_slot = liquid_input_slot
liquid_type = liquid_type
liquid_volume = liquid_volume
slot_on_deck = slot_on_deck
resource = {
"id": res_id,
"class": class_name,
"parent": parent,
"bind_locations": bind_location,
"liquid_input_slot": liquid_input_slot,
"liquid_type": liquid_type,
"liquid_volume": liquid_volume,
"slot_on_deck": slot_on_deck,
}
self.temp_protocol["labwares"].append(resource)
return resources
def transfer_liquid(
self,
sources: Sequence[Container],
targets: Sequence[Container],
tip_racks: Sequence[TipRack],
*,
use_channels: Optional[List[int]] = None,
asp_vols: Union[List[float], float],
dis_vols: Union[List[float], float],
asp_flow_rates: Optional[List[Optional[float]]] = None,
dis_flow_rates: Optional[List[Optional[float]]] = None,
offsets: Optional[List[Coordinate]] = None,
touch_tip: bool = False,
liquid_height: Optional[List[Optional[float]]] = None,
blow_out_air_volume: Optional[List[Optional[float]]] = None,
spread: Literal["wide", "tight", "custom"] = "wide",
is_96_well: bool = False,
mix_stage: Optional[Literal["none", "before", "after", "both"]] = "none",
mix_times: Optional[int] = None,
mix_vol: Optional[int] = None,
mix_rate: Optional[int] = None,
mix_liquid_height: Optional[float] = None,
delays: Optional[List[int]] = None,
none_keys: List[str] = []
):
transfer_params = {
"Span8": False,
"Pod": "Pod1",
"items": {},
"Wash": False,
"Dynamic?": True,
"AutoSelectActiveWashTechnique": False,
"ActiveWashTechnique": "",
"ChangeTipsBetweenDests": False,
"ChangeTipsBetweenSources": False,
"DefaultCaption": "",
"UseExpression": False,
"LeaveTipsOn": False,
"MandrelExpression": "",
"Repeats": "1",
"RepeatsByVolume": False,
"Replicates": "1",
"ShowTipHandlingDetails": False,
"ShowTransferDetails": True,
"Solvent": "Well Content",
"Span8Wash": False,
"Span8WashVolume": "2",
"Span8WasteVolume": "1",
"SplitVolume": False,
"SplitVolumeCleaning": False,
"Stop": "Destinations",
"TipLocation": "BC1025F",
"UseCurrentTips": False,
"UseDisposableTips": True,
"UseFixedTips": False,
"UseJIT": True,
"UseMandrelSelection": True,
"UseProbes": [True, True, True, True, True, True, True, True],
"WashCycles": "1",
"WashVolume": "110%",
"Wizard": False
}
items: dict = {}
for idx, (src, dst) in enumerate(zip(sources, targets)):
items[str(idx)] = {
"Source": str(src),
"Destination": str(dst),
"Volume": dis_vols[idx]
}
transfer_params["items"] = items
transfer_params["Solvent"] = "Water"
TipLocation = tip_racks[0].name
transfer_params["TipLocation"] = TipLocation
if len(tip_racks) == 1:
transfer_params['UseCurrentTips'] = True
elif len(tip_racks) > 1:
transfer_params["ChangeTipsBetweenDests"] = True
self.temp_protocol["steps"].append(transfer_params)
return
def instrument_setup_biomek(
self,
id: str,
parent: str,
slot_on_deck: str,
class_name: str,
liquid_type: list[str],
liquid_volume: list[int],
liquid_input_wells: list[str],
):
"""
设置Biomek仪器的参数配置按照DeckItems格式
根据不同的仪器类型容器、tip rack等设置相应的参数结构
位置作为键,配置列表作为值
"""
# 判断仪器类型
instrument_type = self._get_instrument_type(class_name)
config = None # 初始化为None
if instrument_type == "reservoir":
# 储液槽类型配置
config = {
"Properties": {
"Name": id, # 使用id作为名称
"Device": "",
"liquidtype": liquid_type[0] if liquid_type else "Water",
"BarCode": "",
"SenseEveryTime": False
},
"Known": True,
"Class": f"LabwareClasses\\{class_name}",
"DataSets": {"Volume": {}},
"RuntimeDataSets": {"Volume": {}},
"EvalAmounts": (float(liquid_volume[0]),) if liquid_volume else (0,),
"Nominal": False,
"EvalLiquids": (liquid_type[0],) if liquid_type else ("Water",)
}
elif instrument_type == "plate_96":
# 96孔板类型配置
volume_per_well = float(liquid_volume[0]) if liquid_volume else 0
liquid_per_well = liquid_type[0] if liquid_type else "Water"
config = {
"Properties": {
"Name": id, # 使用id作为名称
"Device": "",
"liquidtype": liquid_per_well,
"BarCode": "",
"SenseEveryTime": False
},
"Known": True,
"Class": f"LabwareClasses\\{class_name}",
"DataSets": {"Volume": {}},
"RuntimeDataSets": {"Volume": {}},
"EvalAmounts": tuple([volume_per_well] * 96),
"Nominal": False,
"EvalLiquids": tuple([liquid_per_well] * 96)
}
elif instrument_type == "tip_rack":
# 枪头架类型配置
tip_config = {
"Class": "TipClasses\\T230",
"Contents": [],
"_RT_Contents": [],
"Used": False,
"RT_Used": False,
"Dirty": False,
"RT_Dirty": False,
"MaxVolumeUsed": 0.0,
"RT_MaxVolumeUsed": 0.0
}
config = {
"Tips": tip_config,
"RT_Tips": tip_config.copy(),
"Properties": {},
"Known": False,
"Class": f"LabwareClasses\\{class_name}",
"DataSets": {"Volume": {}},
"RuntimeDataSets": {"Volume": {}}
}
# 按照DeckItems格式存储位置作为键配置列表作为值
if config is not None:
self.temp_protocol["labwares"][slot_on_deck] = [config]
else:
# 空位置
self.temp_protocol["labwares"][slot_on_deck] = []
return
def transfer_biomek(
self,
source: str,
target: str,
tip_rack: str,
volume: float,
aspirate_techniques: str,
dispense_techniques: str,
):
"""
处理Biomek的液体转移操作。
"""
items = []
asp_params = copy.deepcopy(self.aspirate_techniques[aspirate_techniques])
dis_params = copy.deepcopy(self.dispense_techniques[dispense_techniques])
asp_params['Position'] = source
dis_params['Position'] = target
asp_params['Volume'] = str(volume)
dis_params['Volume'] = str(volume)
items.append(asp_params)
items.append(dis_params)
transfer_params = {
"Span8": False,
"Pod": "Pod1",
"items": [],
"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_params["items"] = items
transfer_params["Solvent"] = 'Water'
transfer_params["TipLocation"] = tip_rack
tmp={'transfer': transfer_params}
self.temp_protocol["steps"].append(tmp)
return
def move_biomek(
self,
source: str,
target: str,
):
"""
处理Biomek移动板子的操作。
"""
move_params = {
"Pod": "Pod1",
"GripSide": "A1 near",
"Source": source,
"Target": target,
"LeaveBottomLabware": False,
}
self.temp_protocol["steps"].append(move_params)
return
def incubation_biomek(
self,
time: int,
):
"""
处理Biomek的孵育操作。
"""
incubation_params = {
"Message": "Paused",
"Location": "the whole system",
"Time": time,
"Mode": "TimedResource"
}
self.temp_protocol["steps"].append(incubation_params)
return
def oscillation_biomek(
self,
rpm: int,
time: int,
):
"""
处理Biomek的振荡操作。
"""
oscillation_params = {
'Device': 'OrbitalShaker0',
'Parameters': (str(rpm), '2', str(time), 'CounterClockwise'),
'Command': 'Timed Shake'
}
self.temp_protocol["steps"].append(oscillation_params)
return
if __name__ == "__main__":
print("=== Biomek完整流程测试 ===")
print("包含: 仪器设置 + 完整实验步骤")
# 完整的步骤信息从biomek.py复制
steps_info = '''
{
"steps": [
{
"step_number": 1,
"operation": "transfer",
"description": "转移PCR产物或酶促反应液至0.5ml 96孔板中",
"parameters": {
"source": "P1",
"target": "P11",
"tip_rack": "BC230",
"volume": 50
}
},
{
"step_number": 2,
"operation": "transfer",
"description": "加入2倍体积的Bind Beads BC至产物中",
"parameters": {
"source": "P2",
"target": "P11",
"tip_rack": "BC230",
"volume": 100
}
},
{
"step_number": 3,
"operation": "oscillation",
"description": "振荡混匀300秒",
"parameters": {
"rpm": 800,
"time": 300
}
},
{
"step_number": 4,
"operation": "move_labware",
"description": "转移至96孔磁力架上吸附3分钟",
"parameters": {
"source": "P11",
"target": "P12"
}
},
{
"step_number": 5,
"operation": "incubation",
"description": "吸附3分钟",
"parameters": {
"time": 180
}
},
{
"step_number": 6,
"operation": "transfer",
"description": "吸弃或倒除上清液",
"parameters": {
"source": "P12",
"target": "P22",
"tip_rack": "BC230",
"volume": 150
}
},
{
"step_number": 7,
"operation": "transfer",
"description": "加入300-500μl 75%乙醇",
"parameters": {
"source": "P3",
"target": "P12",
"tip_rack": "BC230",
"volume": 400
}
},
{
"step_number": 8,
"operation": "move_labware",
"description": "移动至振荡器进行振荡混匀",
"parameters": {
"source": "P12",
"target": "Orbital1"
}
},
{
"step_number": 9,
"operation": "oscillation",
"description": "振荡混匀60秒",
"parameters": {
"rpm": 800,
"time": 60
}
},
{
"step_number": 10,
"operation": "move_labware",
"description": "转移至96孔磁力架上吸附3分钟",
"parameters": {
"source": "Orbital1",
"target": "P12"
}
},
{
"step_number": 11,
"operation": "incubation",
"description": "吸附3分钟",
"parameters": {
"time": 180
}
},
{
"step_number": 12,
"operation": "transfer",
"description": "吸弃或倒弃废液",
"parameters": {
"source": "P12",
"target": "P22",
"tip_rack": "BC230",
"volume": 400
}
},
{
"step_number": 13,
"operation": "transfer",
"description": "重复加入75%乙醇",
"parameters": {
"source": "P3",
"target": "P12",
"tip_rack": "BC230",
"volume": 400
}
},
{
"step_number": 14,
"operation": "move_labware",
"description": "移动至振荡器进行振荡混匀",
"parameters": {
"source": "P12",
"target": "Orbital1"
}
},
{
"step_number": 15,
"operation": "oscillation",
"description": "振荡混匀60秒",
"parameters": {
"rpm": 800,
"time": 60
}
},
{
"step_number": 16,
"operation": "move_labware",
"description": "转移至96孔磁力架上吸附3分钟",
"parameters": {
"source": "Orbital1",
"target": "P12"
}
},
{
"step_number": 17,
"operation": "incubation",
"description": "吸附3分钟",
"parameters": {
"time": 180
}
},
{
"step_number": 18,
"operation": "transfer",
"description": "吸弃或倒弃废液",
"parameters": {
"source": "P12",
"target": "P22",
"tip_rack": "BC230",
"volume": 400
}
},
{
"step_number": 19,
"operation": "move_labware",
"description": "正放96孔板空气干燥15分钟",
"parameters": {
"source": "P12",
"target": "P13"
}
},
{
"step_number": 20,
"operation": "incubation",
"description": "空气干燥15分钟",
"parameters": {
"time": 900
}
},
{
"step_number": 21,
"operation": "transfer",
"description": "加入30-50μl Elution Buffer",
"parameters": {
"source": "P4",
"target": "P13",
"tip_rack": "BC230",
"volume": 40
}
},
{
"step_number": 22,
"operation": "move_labware",
"description": "移动至振荡器进行振荡混匀",
"parameters": {
"source": "P13",
"target": "Orbital1"
}
},
{
"step_number": 23,
"operation": "oscillation",
"description": "振荡混匀60秒",
"parameters": {
"rpm": 800,
"time": 60
}
},
{
"step_number": 24,
"operation": "move_labware",
"description": "室温静置3分钟",
"parameters": {
"source": "Orbital1",
"target": "P13"
}
},
{
"step_number": 25,
"operation": "incubation",
"description": "室温静置3分钟",
"parameters": {
"time": 180
}
},
{
"step_number": 26,
"operation": "move_labware",
"description": "转移至96孔磁力架上吸附2分钟",
"parameters": {
"source": "P13",
"target": "P12"
}
},
{
"step_number": 27,
"operation": "incubation",
"description": "吸附2分钟",
"parameters": {
"time": 120
}
},
{
"step_number": 28,
"operation": "transfer",
"description": "将DNA转移至新的板中",
"parameters": {
"source": "P12",
"target": "P14",
"tip_rack": "BC230",
"volume": 40
}
}
]
}
'''
# 完整的labware配置信息
labware_with_liquid = '''
[
{
"id": "Tip Rack BC230 TL1",
"parent": "deck",
"slot_on_deck": "TL1",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": []
},
{
"id": "Tip Rack BC230 TL2",
"parent": "deck",
"slot_on_deck": "TL2",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": []
},
{
"id": "Tip Rack BC230 TL3",
"parent": "deck",
"slot_on_deck": "TL3",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": []
},
{
"id": "Tip Rack BC230 TL4",
"parent": "deck",
"slot_on_deck": "TL4",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": []
},
{
"id": "Tip Rack BC230 TL5",
"parent": "deck",
"slot_on_deck": "TL5",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": []
},
{
"id": "Tip Rack BC230 P5",
"parent": "deck",
"slot_on_deck": "P5",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": []
},
{
"id": "Tip Rack BC230 P6",
"parent": "deck",
"slot_on_deck": "P6",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": []
},
{
"id": "Tip Rack BC230 P15",
"parent": "deck",
"slot_on_deck": "P15",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": []
},
{
"id": "Tip Rack BC230 P16",
"parent": "deck",
"slot_on_deck": "P16",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": []
},
{
"id": "stock plate on P1",
"parent": "deck",
"slot_on_deck": "P1",
"class_name": "AgilentReservoir",
"liquid_type": ["PCR product"],
"liquid_volume": [5000],
"liquid_input_wells": ["A1"]
},
{
"id": "stock plate on P2",
"parent": "deck",
"slot_on_deck": "P2",
"class_name": "AgilentReservoir",
"liquid_type": ["bind beads"],
"liquid_volume": [100000],
"liquid_input_wells": ["A1"]
},
{
"id": "stock plate on P3",
"parent": "deck",
"slot_on_deck": "P3",
"class_name": "AgilentReservoir",
"liquid_type": ["75% ethanol"],
"liquid_volume": [100000],
"liquid_input_wells": ["A1"]
},
{
"id": "stock plate on P4",
"parent": "deck",
"slot_on_deck": "P4",
"class_name": "AgilentReservoir",
"liquid_type": ["Elution Buffer"],
"liquid_volume": [5000],
"liquid_input_wells": ["A1"]
},
{
"id": "working plate on P11",
"parent": "deck",
"slot_on_deck": "P11",
"class_name": "BCDeep96Round",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": []
},
{
"id": "working plate on P13",
"parent": "deck",
"slot_on_deck": "P13",
"class_name": "BCDeep96Round",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": []
},
{
"id": "working plate on P14",
"parent": "deck",
"slot_on_deck": "P14",
"class_name": "BCDeep96Round",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": []
},
{
"id": "waste on P22",
"parent": "deck",
"slot_on_deck": "P22",
"class_name": "AgilentReservoir",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": []
},
{
"id": "oscillation",
"parent": "deck",
"slot_on_deck": "Orbital1",
"class_name": "Orbital",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": []
}
]
'''
# 创建handler实例
handler = LiquidHandlerBiomek()
# 创建协议
protocol = handler.create_protocol(
protocol_name="DNA纯化完整流程",
protocol_description="使用磁珠进行DNA纯化的完整自动化流程",
protocol_version="1.0",
protocol_author="Biomek系统",
protocol_date="2024-01-01",
protocol_type="DNA_purification"
)
print("\n=== 第一步:设置所有仪器 ===")
# 解析labware配置
labwares = json.loads(labware_with_liquid)
# 设置所有仪器
instrument_count = 0
for labware in labwares:
print(f"设置仪器: {labware['id']} ({labware['class_name']}) 在位置 {labware['slot_on_deck']}")
handler.instrument_setup_biomek(
id=labware['id'],
parent=labware['parent'],
slot_on_deck=labware['slot_on_deck'],
class_name=labware['class_name'],
liquid_type=labware['liquid_type'],
liquid_volume=labware['liquid_volume'],
liquid_input_wells=labware['liquid_input_wells']
)
instrument_count += 1
print(f"总共设置了 {instrument_count} 个仪器位置")
print("\n=== 第二步:执行实验步骤 ===")
# 解析步骤信息
input_steps = json.loads(steps_info)
# 执行所有步骤
step_count = 0
for step in input_steps['steps']:
operation = step['operation']
parameters = step['parameters']
description = step['description']
print(f"步骤 {step['step_number']}: {description}")
if operation == 'transfer':
handler.transfer_biomek(
source=parameters['source'],
target=parameters['target'],
volume=parameters['volume'],
tip_rack=parameters['tip_rack'],
aspirate_techniques='MC P300 high',
dispense_techniques='MC P300 high'
)
elif operation == 'move_labware':
handler.move_biomek(
source=parameters['source'],
target=parameters['target']
)
elif operation == 'oscillation':
handler.oscillation_biomek(
rpm=parameters['rpm'],
time=parameters['time']
)
elif operation == 'incubation':
handler.incubation_biomek(
time=parameters['time']
)
step_count += 1
print(f"总共执行了 {step_count} 个步骤")
print("\n=== 第三步:保存完整协议 ===")
# 获取脚本目录
script_dir = pathlib.Path(__file__).parent
# 保存完整协议
complete_output_path = script_dir / "complete_biomek_protocol_0608.json"
with open(complete_output_path, 'w', encoding='utf-8') as f:
json.dump(handler.temp_protocol, f, indent=4, ensure_ascii=False)
print(f"完整协议已保存到: {complete_output_path}")
print("\n=== 测试完成 ===")
print("完整的DNA纯化流程已成功转换为Biomek格式")