-
Notifications
You must be signed in to change notification settings - Fork 81
Add support for Hamilton MLPrep #407
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
In the branch of this PR, I'm receiving the following error: from pylabrobot.liquid_handling.backends.hamilton.prep import Prep ---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
Cell In[7], line 1
----> 1 from pylabrobot.liquid_handling.backends.hamilton.prep import Prep
File /mnt/c/Users/cmoschner/pylabrobot/pylabrobot/liquid_handling/backends/hamilton/prep.py:10
7 from typing import Any, List, Optional, Tuple, Union
9 from pylabrobot.liquid_handling.backends import LiquidHandlerBackend
---> 10 from pylabrobot.liquid_handling.standard import (
11 Aspiration,
12 AspirationContainer,
13 AspirationPlate,
14 Dispense,
15 DispenseContainer,
16 DispensePlate,
17 Drop,
18 DropTipRack,
19 Pickup,
20 PickupTipRack,
21 ResourceDrop,
22 ResourceMove,
23 ResourcePickup,
24 )
27 class ParameterTypes(Enum):
28 Void = 0
ImportError: cannot import name 'Aspiration' from 'pylabrobot.liquid_handling.standard' (/mnt/c/Users/camillomoschner/pylabrobot/pylabrobot/liquid_handling/standard.py) @rickwierenga, should this be updated to |
yeah the prep branch was quite old, will fix soon, thanks |
I've updated the Next issue: Sending command: 440006300000020004000400010001000015010002134000000000000103010000021701020000001e001a001701020001002800040000808f4328000400000040401f000000
Received response: 7a0006300000010001000015020004000400010002057600000000000105010000022100020015000f0050003078303030312e3078303045382e3078303230323a307830312c3078303030312c3078304630333b3078303030312e3078303045382e3078303230313a307830312c3078303030322c30783046303300
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[7], line 3
1 lh = LiquidHandler(backend=backend, deck=PrepDeck())
----> 3 await lh.setup()
4 vis = Visualizer(resource=lh)
5 await vis.setup()
File /mnt/c/Users/cmoschner/pylabrobot/pylabrobot/liquid_handling/liquid_handler.py:172, in LiquidHandler.setup(self, **backend_kwargs)
170 self.backend.set_deck(self.deck)
171 self.backend.set_heads(head=self.head, head96=self.head96)
--> 172 await super().setup(**backend_kwargs)
174 self.head = {c: TipTracker(thing=f"Channel {c}") for c in range(self.backend.num_channels)}
175 self.head96 = {c: TipTracker(thing=f"Channel {c}") for c in range(96)}
File /mnt/c/Users/cmoschner/pylabrobot/pylabrobot/machines/machine.py:63, in Machine.setup(self, **backend_kwargs)
62 async def setup(self, **backend_kwargs):
---> 63 await self.backend.setup(**backend_kwargs)
64 self._setup_finished = True
File /mnt/c/Users/cmoschner/pylabrobot/pylabrobot/liquid_handling/backends/hamilton/prep.py:267, in Prep.setup(self)
264 self.socket.connect((self.host, self.port))
265 self.socket.settimeout(30)
--> 267 await self.initialize(
268 tip_drop_params=Prep.InitTipDropParameters(
269 default_values=True,
270 x_position=287.0,
271 rolloff_distance=3,
272 channel_parameters=[],
273 ),
274 smart=False,
275 )
277 await super().setup()
File /mnt/c/Users/cmoschner/pylabrobot/pylabrobot/liquid_handling/backends/hamilton/prep.py:3249, in Prep.initialize(self, tip_drop_params, smart, timeout)
3243 async def initialize(
3244 self,
3245 tip_drop_params: InitTipDropParameters,
3246 smart: bool = False,
3247 timeout: Optional[float] = None,
3248 ) -> None:
-> 3249 return await self.send_command(
3250 command_id=1,
3251 parameters=[
3252 (smart, ParameterTypes.Bool),
3253 (tip_drop_params, ParameterTypes.Structure),
3254 ],
3255 timeout=timeout,
3256 harp_source=self.source_address,
3257 harp_destination=self.destination_address,
3258 )
File /mnt/c/Users/cmoschner/pylabrobot/pylabrobot/liquid_handling/backends/hamilton/prep.py:378, in Prep.send_command(self, command_id, parameters, harp_source, harp_destination, hoi_action, timeout)
375 response = self.socket.recv(1024)
376 print("Received response:", response.hex())
--> 378 self._decode_response(response)
File /mnt/c/Users/cmoschner/pylabrobot/pylabrobot/liquid_handling/backends/hamilton/prep.py:352, in Prep._decode_response(self, response)
350 if len(fragments) > 0 and fragments[0]["format"] == ParameterTypes.HcResult:
351 if fragments[0]["fragment_data"] != 0:
--> 352 raise ValueError(f"Command failed with error code {fragments[0]['fragment_data']}")
354 return
ValueError: Command failed with error code 21 I can see the channels starting to initialise (even the fixed-distance 8-channel head), i.e. move to the front of the arm (performing a flagsearch?), followed by moving into their "default" position. |
based, can make a branch on your repo and PR into plr:prep?
As far as I understand the prep firmware, this maps to Printing the fragments in this string I get:
... i don't know what fyi, we don't have the 8 channel head |
a similar error found in a trace file i got from the prep:
this part stands out:
(spacing added for readability) 0x0F04 is 0d3844, which is in the same range as other
the part before the colon could be the address for the two 'heads' (1 & 8 channel). do you have two? One of the parameters of |
A (nearly) complete firmware implementation for the Hamilton MLPrep, including the ip layer, harp2 (hamilton robot protocol?) and hoi2. Tested the big five (setup, tip pickup, tip drop, aspirate, dispense) on ours. This is the world's first interface to the Prep that doesn't use the internal computer & touch screen: you can now properly program it.
Plug your computer into the robot's ethernet port (should be a passthrough to the internal board). Assign a static ip to your computer in the
192.168.100.x
range, but not192.168.100.102
since that's the robot's static ip.TODO: