Opentrons: bug: When targeting a location somewhere above the top of a well, pipette first moves to exact top of the well, then moves vertically up

Created on 11 Aug 2020  Â·  17Comments  Â·  Source: Opentrons/opentrons

Overview


Working with a non-standard pipette tip length. I can calibrate to the new length just fine. However, if I also want to use standard pipettes in the same python protocol it is not currently possible. If I calibrate with a standard tip I can set the height via the location definition. However, when aspirating it first moves to the set calibration height before moving to the specified height above the well. This would smash the non-standard pipette tip into the deck.

Implementation details

I would propose that the robot calculates where to move and aspirate from it's current position instead of the calibration point if given a specific location or that if a move_to() call is used prior to an aspirate() that the robot determines it's path based on it's current position instead of from the calibration position.

Design

Ideally, I would like to calibrate and use a standard pipette tip along side a custom tip length. So calibrating with a standard tip length but specifying a custom aspirate height without smashing the custom tip would be helpful for some procedures. Ideally some custom setter to tell the robot when the tip is attached would be an added benefit. I'm currently just telling the OT-2 to pick up a tip from an empty location and then pausing to add the custom pipette.

Acceptance criteria

Pipetting from a set location above the well does not dip to calibration point before aspirating. Or other suitable workaround.

bug cpx papi v2

All 17 comments

Thanks for opening this issue!

However, if I also want to use standard pipettes in the same python protocol it is not currently possible.

So, for example, if your protocol uses a P300, you want that P300 to use Opentrons 300 µL tips in some parts of the protocol, and tips from another company in other parts of the protocol?

If I calibrate with a standard tip I can set the height via the location definition. However, when aspirating it first moves to the set calibration height before moving to the specified height above the well. This would smash the non-standard pipette tip into the deck.

Sorry, I don't think I understand.

Could you clarify what do you mean by "set the height via the location definition"?

Yes, Right now I'm trying to use just a single P1000 (Gen 2). I'm using an in-house made pipette tip. Ideally we would want to swap tips between a custom tip and an opentrons tip with the p1000 mid protocol.

The custom tip is much longer than the standard pipette tip (7.5cm). I can specify the aspirate via a location class instance say p1000.aspirtate(1000, plate['A1'].top(75)) for example. It does go to that location to aspirate. However, the robot first jogs to the top of the well height as calibrated before moving to the specified height which would smash the tip into the deck (I fortunately tested this before trying it). This makes sense if the height specified is below the top of the well but If I specify a height above the labware definition I would expect it to go to that location and not the top of the well as calibrated first.

Additionally, If I dispense in the same fashion i.e.p1000.dispense(plate['A2'].top(75)) it moves to the correct height immediately without first moving to the top of the well and dispenses.

I guess I could just calibrate with the custom tip and then specify negative values for the opentrons tip but I am unaware of any warnings or Errors if I go below where it thinks the deck is in relation to the Labware.

Hi @Dardin-dale ! Quick question, are you using a custom tiprack definition for your custom tip? The ultimate source of the tip length in the geometry system comes from these two values:

https://github.com/Opentrons/opentrons/blob/03c305175477259b3b492e99d12d0034e2c348f9/shared-data/labware/definitions/2/opentrons_96_tiprack_1000ul/1.json#L1006-L1007

Off the top of my head, I'm not sure how the tip length gets set when you have two different tiprack definitions for the pipette, but I am thinking that if you do p1000.pick_up_tip(tall_tiprack['A1']) before doing the aspirate command with the custom tip, this might work around the issue you are seeing.

You can find more info on creating labware definitions here.

Thank you! I've been going on the website labware library page and I didn't see any mention of custom tiprack definitions (only plate definitions) so I thought it was not implemented. But I'll try making a dummy definition to see what the behavior is.

I might make my own definition for a pick_up_tip() eventually since I'm not sure if the tip that we are using will survive the shaking. Is there a state value that I can change to inform the OT-2 that a tip is attached?

Not sure If I should keep this thread going @nickcrider or move it somewhere else. I haven't been able to make a protocol that uses two different length tip racks I seem to keep getting odd labware height errors where if I make a seemingly correct definition for the custom tip rack it then complains about the standard Opentrons tip rack for labware height. I haven't quite figured out how to properly access/manipulate the tip_length or has_tip settings through the the instrument context in the protocol. I've seen a protocol that uses a .hw_pipette dictionary attribute but it doesn't seem to exist in the up to date version of the instrument context.

Hey @Dardin-dale, thanks for following up! Have you noticed any patterns in when you see the labware height errors pop up? The tip probe process (touching the switches under the trash during calibration) sometimes can contribute to these errors. Have you tried skipping it?

We're currently in the process of overhauling calibration under the hood, and a big part of that is changing how tip length works in the system. So hopefully this issue to get better with future software updates. But for now unfortunately, I don't think there's any official way to modify tip_length or has_tip from the protocol context.

Feel free to continue here, or with one of my colleagues at [email protected]

The Labware height issues show up in the simulation process so I'm not even getting to the tip probe process/calibration. I think the part that was confusing me was that the wording of the error is: "opentrons.protocol_api.execute.ExceptionInProtocolError: LabwareHeightError [line 216]: The Custom Tip Rack 1000 µL on 5 has a total height of 132.25 mm, which is too tall for your current pipette configurations. The longest pipette on your robot can only be raised to 99.09 mm above the deck." Where the height it gives is the height above the labware, not the deck. So after some trial and error I was able to get that working.

Here is the lines of protocol code that I'm playing with:

p1000.pick_up_tip(custom_tiprack.wells()[0])
p1000.drop_tip()
p1000.pick_up_tip(normal_tiprack.wells()[0])

I think I was mistaken since I've been fudging labware definitions for a tiprack that doesn't physically exist. max deck height I have to use (zDimension + tip_length) is about 231mm from the error messages. so if I make a definition:

"dimensions": {
    "xDimension": 127.75,
    "yDimension": 85.5,
    "zDimension": 115.5
  },
  "parameters": {
    "format": "96Standard",
    "isTiprack": true,
    "isMagneticModuleCompatible": false,
    "tipLength": 110.9,
    "tipOverlap": 11.2,
    "loadName": "custom_tiprack_1000ul"
  }

this does not give me the same simulator error as it would for a longer tip. I'll test if this actually has the desired behavior tomorrow. I can also make that zDimension 10mm with no error... not sure where the robot would attempt the pick up in that case. I'll have to see if I need some physical stopper for the robot to hit in the pick_up_tip() for the custom labware.

I think that the has_tip and tip_length would be helpful. Or bringing the hardware control api's add_tip() to the instrument context api would be useful in my situation. Since we are dealing with glass we either need to do a lot of testing with a pick_up() or just have the user load on the glass at a protocol pause.

So with some trial and error. I can get different length tips to get loaded into the labware and move past the simulation and calibration. However, when I start to run the protocol I am hitting a SmoothieError I'm not sure how to overcome:

SmoothieError [line 217]: SmoothieError: M907 A0.1 B0.05 C0.05 X0.3 Y0.3 Z0.8 G4P0.005 G0Z205.695 returned ALARM: Hard limit +Z

This occurs after trying to pick up a tip from the custom definition. I've played around with the height of the labware as well as the calibrated height. The last value (G0ZXXXXX) seems to change based on those variables. I'm not sure what my limitations are here. I've also tried loading in just the custom definition without the standard tiprack with similar results.

@nickcrider are there hard limits on the tip geometry as it is currently implemented?

Well now my previous labware calibration work around for a single tip (pick up a normal tip, switch to the glass tip and calibrate to the glass tip in the labware set-up) seems to be patched over and I keep running into that smoothie error after I perform a pick_up_tip during a protocol run. It seems like this is a pretty active part of the development sprint right now. I'm going to see if I can roll back a few commits so that my work around works again and watch HMG Sprints 17 and 18 since they seem to be adjusting how this process works. If anyone has additional recommendations I would love to hear them!

Update here, I've tested and I reverted to 3.20.0 as the patch in 3.20.1 stopped my Z-axis labware calibration work around. I tried to use the new calibration paradigm beta build that I just downloaded through the app and turned on the __Dev__ setting. I think that I needed to have re-performed the Deck calibration after that as I definitely smashed a few tips in the process and reverted to 3.20.0 and had to re-perform the deck calibration twice before getting normal use. My calibration work around is working for a single pipette on 3.20.0 but I run into that Smoothie error if I try to use a second pipette to do the work with a normal pipette. I might try the beta build again and re-perform deck calibration as a next step.

Updated my software to 4.0.0, So far it is working alright, The Deck calibration is a great improvement . Every now and then my calibration workaround causes the robot to hit a z-axis error unrecoverably since I'm close to the maximum, So I factory reset my pipette & tip calibrations and it will work again. Going to try and use tip geometry instead of calibrating the the labware to a large Z-axis soon.

I am unable to use the tiplength geometry effectively still the protocol hangs after a pick_up_tip() with the custom tiprack definition. Sometimes it calls out a hard Z limit error that I can't overcome and eventually forces me to reset all of the pipette offset calibration data.

That said I've found a new potential workaround through the Labware.set_calibration() method. Where I can calibrate labware with the second p20 multichannel head (standard tips) and then set the calibration plate.set_calibration(opentrons.types.Point(0,0,94)) before using the long tip and then reset it (0,0,0) to use the standard tip. I was a little surprised that it is a public method since it's a helper function but glad it's available.

It happens to me also, but not with a custom but a regular tiprack (20 ul).
Interestingly it happens only after physically switching off the OT2(i had
to switch off because of planned electrical maintenance). From that on i
cannot recalibrate since it hangs on with pick_up_tip or return tip during
tiprack calibration but also at tip length or offset calibration.

Skipping calibration will result in an error like
"opentrons.protocols.geometry.planning.LabwareHeightError: The Opentrons 96
Tip Rack 20 µL on 2 has a total height of 141.17499999999998 mm, which is
too tall for your current pipette configurations. The longest pipette on
your robot can only be raised to 138.17000000000002 mm above the deck. This
may be because the labware is incorrectly defined, incorrectly calibrated,
or physically too tall. This could also be caused by the pipette and its
tipracks being mismatched. Please check your protocol, labware definitions
and calibrations."

Factory reset helps, but it is really annoying.
It doesn't happen after a soft reboot.

On Fri, Dec 11, 2020 at 11:56 PM Logan Crecraft notifications@github.com
wrote:

I am unable to use the tiplength geometry effectively still the protocol
hangs after a pick_up_tip() with the custom tiprack definition. Sometimes
it calls out a hard Z limit error that I can't overcome and eventually
forces me to reset all of the pipette offset calibration data.

That said I've found a new potential workaround through the
Labware.set_calibration() method. Where I can calibrate labware with the
second p20 multichannel head (standard tips) and then set the calibration
plate.set_calibration(opentrons.types.Point(0,0,94)) before using the
long tip and then reset it (0,0,0) to use the standard tip. I was a little
surprised that it is a public method since it's a helper function but glad
it's available.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/Opentrons/opentrons/issues/6323#issuecomment-743469101,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ANKEXOF5HPC4PAFMASQB47DSUKPRXANCNFSM4P3J3ONA
.

The problem reported in the original post still exists on robot software v4.2.1, Python Protocol API v2.9.

metadata = {
    'apiLevel': '2.9'
}

def run(protocol):
    tip_rack = protocol.load_labware('opentrons_96_tiprack_300ul', 2)
    plate = protocol.load_labware('corning_384_wellplate_112ul_flat', 1)
    pipette = protocol.load_instrument('p300_multi_gen2', mount='right', tip_racks=[tip_rack])

    pipette.pick_up_tip(tip_rack['A1'])

    # Expected behavior: Move in an arc to 10 cm above the plate, then aspirate
    # in place.
    #
    # Actual behavior: Move in an arc to the top of the plate, then move 10 cm
    # straight up, then aspirate in place.
    pipette.aspirate(300, plate['A1'].top(100))

    pipette.return_tip(tip_rack['A1'])

To make it easier for us to understand and keep track of this issue, I've hidden the comments in this thread that seem to be talking about other things.

I don't mean to imply that those things are unimportant or not worthy of discussion—just that they're separate. If you're still seeing those problems on the latest robot software version (currently v4.2.1), please reach out to Opentrons Support or create a new GitHub issue—we want to fix them!

MLM - address in future

Was this page helpful?
0 / 5 - 0 ratings