Opentrons OT2 "protocol.max_speeds" Command Not Working, Known Limitation; Plans for API 2.14 and Up?

Hello,

I recently updated my Opentrons OT2s to Robot Version 6.3.1. Among other things, I was excited to be able to use the new “define_liquids” and “well.load_liquid” in API version 2.14 to make things easier for the operators of the OT2s.

I was disappointed to see that the “protocol_context.max_speeds” command is not working on API version 2.14 at this point and is a known limitation. The suggested workaround is to use “InstrumentContext.default_speed” or “the per method speed argument”. I don’t see any documentation anywhere about the second option, so not sure how to try that.

I use the protocol_context.max_speeds quite heavily in my code, specifically to control the z-Axis speed for my pipettes to ensure that i don’t bring extra liquid out with me as the pipette tips withdraw from the liquids after i dispense, and then resetting it to be faster once i have done a blowout to quickly get the tips to the trash. I also use it to slow down the pipetting speed when moving out of a liquid after aspirating as well. Begin able to modify these speeds has helped optimize the speed of my protocols and the reliability of the pipetting.

The “InstrumentContext.default_speed” would slow down the entire gantry; does that include the Z axis, or is it just the X and Y movement? The example given in the API docs shows it used with pipette.move_to ; will it only work movement type commands like “.move_to”? Or will it work if I wrap it around pipetting commands?

I.e. is what I normally do below:

        protocol_context.max_speeds['Z'] = 20 # Set Speed of Z Axis
        pipette.well_bottom_clearance.aspirate = 1
        pipette.well_bottom_clearance.dispense = 1
        pipette.mix(1, dilution_volume_1, dilution_buffer)
        pipette.well_bottom_clearance.aspirate = 1
        pipette.well_bottom_clearance.dispense = 1
        pipette.aspirate(dilution_volume_1, dilution_buffer)
        protocol_context.max_speeds['Z'] = 100 # Set Speed of Z Axis
        pipette.dispense(dilution_volume_1, target)
        protocol_context.max_speeds['Z'] = 20 # Set Speed of Z Axis
        protocol_context.delay(seconds=3)
        pipette.blow_out(target.bottom(9.5))
        pipette.touch_tip(v_offset=-5, speed=50, radius=0.5)
        protocol_context.max_speeds['Z'] = 100 # Set Speed of Z Axis

the same as below:

        pipette.default_speed = 100 = 20 # Set Speed of Z Axis
        pipette.well_bottom_clearance.aspirate = 1
        pipette.well_bottom_clearance.dispense = 1
        pipette.mix(1, dilution_volume_1, dilution_buffer)
        pipette.well_bottom_clearance.aspirate = 1
        pipette.well_bottom_clearance.dispense = 1
        pipette.aspirate(dilution_volume_1, dilution_buffer)
        pipette.default_speed = 100 # Set Speed of Z Axis
        pipette.dispense(dilution_volume_1, target)
        pipette.default_speed = 20 # Set Speed of Z Axis
        protocol_context.delay(seconds=3)
        pipette.blow_out(target.bottom(9.5))
        pipette.touch_tip(v_offset=-5, speed=50, radius=0.5)
        pipette.default_speed = 100 # Set Speed of Z Axis

If not, any ideas on how to accomplish what I am trying to do in the meantime?

What is the plan for the “protocol_context.max_speeds”? Is this being deprecated? Or is there a fix in the works? I poked around on the Opentrons GitHub but couldn’t find any current issues raised about it. If the above code will not accomplish what I am looking to do, then I won’t be able to use the new liquid commands until it is fixed.

@MeghanFerzoco , who should I tag in the future for questions like this? I’m very happy to see Opentrons officially more active on the forum!

Hey @UCantBcereus, you can tag @FLEXpert on the forum to answer these as well. For our documentation purposes, can you send this to support@opentrons.com and copy me (meghan.ferzoco@opentrons.com)? I will make sure that the answer also gets posted here (like the last question). This allows us to update our internal help center and keeps things centralized.

Thank you!

1 Like

Hi!

I am a Support Engineer at Opentrons who was discussing this issue with UCantBcereus.

Here is a review of the options with a couple of application notes:

  • If you set a default speed, it is for all motor axises.
  • If you set a default speed, you need to set it back to its default speed of 400 meters/second

Use default_speed


def aspirate_special(vol, location)
     pipette.default_speed = 50
     pipette.aspirate(vol, location)
     pipette.default_speed = 400 

In this step, I exclusively lowered the aspirate step. This can be a bit of a pain even when using “find and replace” tools to then keep resetting it to default.

I might make a custom aspirate function and call that instead

The alternative, calling it every time

If you call it every time, the code gets pretty hectic with having to reset the default speed to normal every time.

    protocol.comment('going to do it with default_speed lowering to 50 only for the aspirate')
    p300_multi.pick_up_tip()
    p300_multi.default_speed = 50
    p300_multi.aspirate(100, well_plate['A1'].bottom())
    p300_multi.default_speed = 400
    p300_multi.dispense(100, well_plate['A1'].bottom())
    p300_multi.drop_tip()
Use move_to
    p300_multi.pick_up_tip()
    protocol.comment('Here is a move_to with a speed of 20mm/sec')
    p300_multi.move_to(well_plate['A1'].bottom(), speed = 50)
    p300_multi.aspirate(100)
    p300_multi.dispense(100)
    p300_multi.drop_tip()

Stick to 2.13 and below

This is not really a “solution” so much as an option in case you don’t want to update each protocol for 2.14.

Long term

I have posted this as a feature request to our product team and we will look into it long-term.

2 Likes

Hi All,

We were finally able to test this last week.

When switching to

pipette.default_speed = 20 # Set Speed of Z Axis

from

protocol_context.max_speeds['Z'] = 20# Set Speed of Z Axis

we found that for 8 samples, this increased our run time 1.5 minutes( 9.5 minutes to 11 minutes). If we ran our Max Sample # of 48 samples, then we would have increased our run time 9 minutes. If we were processing a full 96 samples, then this would increase the run time by 18 minutes.

I’m not sure if the increased run time is worth the additional Visual Prompts you get during protocol setup, but it may be for others.

Hope this helps someone in the future!

3 Likes