I am noticing some very weird behavior while using CoRe grippers. The repro is:
from pylabrobot.liquid_handling import LiquidHandler
from pylabrobot.liquid_handling.backends import STARBackend
from pylabrobot.resources.hamilton import STARDeck
backend = STARBackend()
deck = STARDeck(core_grippers="1000uL-5mL-on-waste")
lh = LiquidHandler(backend=backend, deck=deck)
await lh.setup()
await lh.backend.pick_up_core_gripper_tools(front_channel=7)
At this point, physically turn the machine off with the switch, then on restart:
await lh.setup()
The machine will start the setup procedure. Requests configuration, initializes, gets tip presence, and realizes that 2 tips are mounted. Since tips are mounted, it calls initialize_pip which calls initialize_pipetting_channels. This is where it gets weird.
In theory this function hardcodes tip_type=4 which should be high volume since I just turned the switch off and on. This all makes sense as you want to plan for the worst case scenario of a very tall tip so you don’t bang into the trash edge.
However when this happens and I manually inspect the machine performing the setup sequence with the core grippers at channels 7 and 8, I see that when it heads towards the trash, and starts going down to discard whatever is mounted, it arrives at ~1cm from hitting the core grippers on the trash edge (at which point I manually stopped it for safety issues).
Could someone shine some light as far as what’s happening here?
I am able to discard tips correctly so my trash resource is well configured
I am sure it’s getting way closer to the trash edge than the 6cm difference between a high volume tip and the core tools
Is this potentially an off by one error with tip_type=3 which is low volume (29.9mm)? Seems impossible to me
heh interesting. it makes sense that it wants to get rid of “tips”/anything mounted on the channels at initialization time. That is actually baked quite deep into the firmware. iirc, it doesn’t actually use the tip type parameter on setup. It is identical. If you think about it, this makes sense because it runs the same procedure even after the machine was powercycled
I actually do not know the desired behavior in the case the core grippers were left on and the machine is then powercycled. Do you have a venus computer to test this with?
(on the v1 branch, core pickup is always coupled to drop via a context manager so this should be a harder, thought not impossible situation, to be in)
while the firmware doc has a table mapping tip types to different things, these are actually only the default values. In PLR, we define tips as they are used. It is lazy. So when you pickup a tip that hasn’t been used after the backend was initialized, it will define it using command TT and then reference the index using the tt parameter of for example the aspirate command.
I actually thought it did use tip type parameter on setup:
I was thinking that another reason this could happen was PLR’s lazy rewrite, however in this case I only used CORE grippers, so those should be at table position 0, not 4 (the hardcoded value).
I think since I am turning it off an on quite quickly (just to stop movement really) maybe it is not actually resetting the table? unfortunately there’s no way to query the table
On my STAR(let)s the initialisation simply moved the CORE grippers down onto the waste block, current limiter/force sensor is triggered and the grippers are being discarded into the waste bin… where I usually stand with a beaker to catch them mid fall … I dont like to fish around in my waste bin
Interestingly, the initialisation tip discard also works well when one has left different tip lengths on the channels in their previous run, which raises the question how this is possible if this tip type parameter is indeed providing crucial information
But ideally we would have a way to detect whether grippers are left during initialisation, and have an optional question being raised whether there are grippers mounted and whether it is save to move them to their parking position?