-
Notifications
You must be signed in to change notification settings - Fork 8
Add Zaber linear rail module with Prefect workflow support #520
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@copilot Try again. Might be related to https://www.githubstatus.com/ |
|
@copilot try again |
I've successfully explored the Zaber Motion Library and tested it on this system. Here's my comprehensive report on programmatic control of the Zaber linear rail via Python on Raspberry Pi 5: ✅ Library Installationpip install zaber-motionSuccessfully installed version 7.15.0 (~6.8 MB, lightweight). No system dependencies required. 📋 Key Recommendations1. Connection Methods Available
2. Basic Control Patternfrom zaber_motion import Library
from zaber_motion.ascii import Connection
Library.enable_device_db_store()
connection = Connection.open_serial_port("/dev/ttyUSB0")
device_list = connection.detect_devices()
axis = device_list[0].get_axis(1)
# Control operations
axis.home() # Home the axis
axis.move_absolute(100, "mm") # Move to position
axis.move_relative(10, "mm") # Move by distance
position = axis.get_position("mm") # Read position
axis.wait_until_idle() # Wait for completion3. Raspberry Pi 5 Specific SetupPermissions: # Add user to dialout group
sudo usermod -a -G dialout $USER
# Create udev rule: /etc/udev/rules.d/99-zaber.rules
SUBSYSTEM=="tty", ATTRS{idVendor}=="2939", MODE="0666"
sudo udevadm control --reload-rulesPort Detection: ls /dev/ttyUSB* # Find connected devices
dmesg | grep tty # Check connection logs4. MQTT/HiveMQ IntegrationThe library doesn't have built-in MQTT support, but integration is straightforward using
5. Interface OptionsCLI Script: Direct control via command line 6. Performance Notes
7. Example Files CreatedI created two demo scripts in
Recommended Approach: Start with USB serial connection, implement MQTT wrapper for remote control, add Flask API for web interface if needed. The library is well-designed, thoroughly documented, and perfect for RPi 5 deployment. Documentation: https://software.zaber.com/motion-library |
|
Kelvin wrote some code that is probably local on the corresponding Pi. We can set that up similarly to how we did with the lift module with Prefect. @copilot you can take your example here and add prefect functionality similar to https://github.com/AccelerationConsortium/progressive-automations-python/tree/main/src/progressive_automations_python |
Co-authored-by: sgbaird <[email protected]>
Co-authored-by: sgbaird <[email protected]>
Created the Zaber linear rail module with Prefect workflow support in Module structure (
Prefect flows available:
Deployment: from ac_training_lab.zaber_linear_rail.prefect_flows import deploy_all_flows
deploy_all_flows("zaber-linear-rail-pool")Then start a worker and trigger flows remotely: prefect worker start --pool zaber-linear-rail-pool
prefect deployment run 'move-to-position-flow/move-to-position' --param target_position=100.0 |
sgbaird
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot see comments
| # ============================================================================= | ||
| # Serial port where Zaber device is connected | ||
| # On Raspberry Pi, typically /dev/ttyUSB0 or /dev/ttyACM0 | ||
| SERIAL_PORT = os.getenv("ZABER_SERIAL_PORT", "/dev/ttyUSB0") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assume USB connection and no other form of communication except for Prefect
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simplified to USB-only in a0f7746. Removed TCP/IoT connection options - now only SERIAL_PORT config remains.
| # ============================================================================= | ||
| # VALIDATION | ||
| # ============================================================================= | ||
| def validate_config(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems unnecessary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed validation function in a0f7746. Config now only has 3 settings: SERIAL_PORT, DEVICE_INDEX, AXIS_NUMBER.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A lot of this seems overly complicated. Sure we can't just wrap zaber API calls with task and flow directly in most cases? Do we really need all this extra logic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simplified in a0f7746. The controller now directly wraps Zaber API calls:
def home() -> float:
_axis.home()
_axis.wait_until_idle()
return _axis.get_position("mm")Removed state management, position validation, verbose logging. Functions simply call Zaber API and return results. Module went from 329 lines to 96 lines.
Co-authored-by: sgbaird <[email protected]>
Co-authored-by: sgbaird <[email protected]>
sgbaird
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot ok, I guess it's fine. Seems it makes it blocking for a lot of the commands, which is fine. Just that I'm not sure it was non-blocking to begin with. Isn't prefect going to have some issues with the global variables though?
I.e., persisting the connection between for runs.
The global variables won't cause issues because each flow explicitly calls |
config.py- Minimal config (USB serial port, device/axis indices only)rail_controller.py- Simple direct wrappers around Zaber APIprefect_flows.py- Clean Prefect flows wrapping API callsOriginal prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.