This folder contains the xArm 7 plate-shuttling workflow for moving a 96-well plate between the BugPicker and the imager/plate-reader station.
The main script, Plate_shuttle_cycle.py, performs one complete automated cycle:
- Open gripper and move to the BugPicker start area.
- Pick up the 96-well plate from the BugPicker.
- Transfer the plate to the imager.
- Release the plate and move to the imaging wait pose.
- Run the plate-reader scan script:
/home/biokea-06/Documents/PlateReader/scan96.py. - Pick the plate back up from the imager.
- Return and release the plate onto the BugPicker.
- Retract and return to the home travel pose.
This workflow was built as part of the AI Science World Model Hack Hub Zeon Systems hackathon.
The goal was to demonstrate how AI-assisted software development and robotics can automate a real biological discovery bottleneck: moving 96-well plates between organism-handling, imaging, and scanning stations.
- uFactory xArm 7
- xArm gripper
- BugPicker station
- Imager / plate-reader station
- 96-well plate workflow
Use the Python virtual environment that has the xArm SDK and plate-reader dependencies installed:
source ~/Documents/xarm-venv/bin/activateThe main script imports xarm.wrapper.XArmAPI and runs the plate-reader script with the same Python executable:
PLATE_READER_SCAN = [sys.executable, "/home/biokea-06/Documents/PlateReader/scan96.py"]From this folder:
cd ~/Documents/BugPicker_arm
source ~/Documents/xarm-venv/bin/activate
python Plate_shuttle_cycle.pyThe script pauses before motion:
Arm enabled. Clear the workspace, then press Enter to start the cycle...
Only press Enter after the workspace is clear and the plate/fixtures are ready.
Robot controller IP:
ARM_IP = "192.168.1.209"Motion speeds:
SPEED_LINEAR = 50
SPEED_NORMAL = 30
SPEED_CARRY = 15Gripper settings:
GRIP = 755
RELEASE = 850
GRIPPER_CLOSE_SPEED = 2000
GRIPPER_OPEN_SPEED = 500Release timing:
PRE_RELEASE_DWELL = 2.0
POST_RELEASE_DWELL = 2.0Approach height:
APPROACH_Z_OFFSET_MM = 50.0- Keep a hand near the emergency stop during tests and demos.
- Do not open the gripper manually or in software while the plate is unsupported.
- The script includes a one-time retry for motion stop error
-9. It clears state and retries the same motion once without changing the gripper state. - If a retried move also fails, the script stops.
- Payload values are still placeholders. Update
PAYLOAD_EMPTYandPAYLOAD_LOADEDbefore increasing speed or running extended unattended cycles.
Plate_shuttle_cycle.py includes check_motion(...), which handles intermittent xArm stop-state motion failures:
motion returns code -9
clear warning/error
set arm ready
retry the same motion once
continue if retry succeeds
stop if retry fails
This was added because the carried move into transit_safe occasionally entered state=4, while a cleared retry succeeded.
Use these scripts to test individual sections instead of running the full cycle.
00_read_current_pose.py Print current TCP pose and joint angles.
01_test_gripper.py Test gripper open/close.
02_test_pickup_vertical.py Test BugPicker pickup approach, grip, and lift.
03_test_drop_vertical.py Test placing the plate onto the imager.
04_test_transit.py Test home/transit/wait movement poses.
05_test_forward_no_return.py Test BugPicker -> imager only.
06_test_imager_pickup_vertical.py Test pickup from the imager.
07_test_return_to_bugpicker.py Test imager -> BugPicker return.
08_record_intermediate_pose.py Record new taught poses from the current arm position.
Run a test script like this:
cd ~/Documents/BugPicker_arm
source ~/Documents/xarm-venv/bin/activate
python 02_test_pickup_vertical.pyThe main workflow uses Cartesian poses in the form:
[x, y, z, roll, pitch, yaw]Units:
x/y/z = mm
roll/pitch/yaw = degrees
Current primary poses are defined in Plate_shuttle_cycle.py and mirrored in arm_common.py for the test scripts.
A short project deck is also in this folder:
BugPicker_biodiversity_robotics_deck.pptx
It summarizes the project idea, hypothesis, demo, impact, and next steps.