-
Notifications
You must be signed in to change notification settings - Fork 180
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
feat(shared-data, api): add stacker max fill height in shared-data definition #17609
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## edge #17609 +/- ##
==========================================
- Coverage 25.71% 24.78% -0.93%
==========================================
Files 2843 2850 +7
Lines 218900 219418 +518
Branches 17949 18126 +177
==========================================
- Hits 56284 54380 -1904
- Misses 162601 165024 +2423
+ Partials 15 14 -1
Flags with carried forward coverage won't be shown. Click here to find out more.
|
|
||
def get_height_of_stacker_labware_pool(self, module_id: str) -> float: | ||
"""Get the overall height of a stack of labware in a Stacker module.""" | ||
stacker = self._modules.get_flex_stacker_substate(module_id) |
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.
stacker could be None here
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.
I didn't think we'd need to handle when it returns None because the only time this function will be called from a stacker command, and the command should fail anyway if there's no stacker attached?
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.
Brayans right, probably want to handle the None case for good developer support, since this function is in general geometry. Anything with access to geometry could in theory call it in the future.
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.
I think I'm missing something here.
My understanding is that if there's no stacker attached, the get_flex_stacker_substate
would raise a ModuleNotLoadedError
. If the module id doesn't belong to a stacker, a WrongModuleTypeError
would be then raised instead.
When would we get a None here?
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.
Ah you know what, youre right we are handling that case when looking through the dict of loaded modules.
|
||
def get_stacker_max_fill_height(self, module_id: str): | ||
"""Get the maximum fill height for the Flex Stacker.""" | ||
definition = self.get_definition(module_id) |
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.
also could fail with None
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.
very nice, thank you.
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.
Looks excellent to me, thank you!
primary_definition: LabwareDefinition | ||
lid_definition: LabwareDefinition | None | ||
adapter_definition: LabwareDefinition | None | ||
# if the pool is changed we must also update the max pool count |
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.
i don't think we need this comment because we added max_pool_count
to the FlexStackerPoolConstraint
class, so it's impossible to forget to update it
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.
that's true!
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.
Looks solid overall, just some comments down below.
pool_height = self._state_view.geometry.get_height_of_labware_stack( | ||
[x for x in [lid_def, labware_def, adapter_def] if x is not None] | ||
) |
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.
This will work great for now, however labware that doesn't have stacking offsets will have a "naive" view of overall stack height. Something like a Tiprack -> Tiprack stack or Tiprack -> Lid -> Tiprack stack. In short terms, because these labware do not have a stackingOffsetWithLabware keyed by the URI of the labware they're going to sit on top of, they default to an overlap of 0. This means the geometry calculator is assuming that they are a pure "block" defined by z-height. This is fine, but it does mean we're over-estimating our stacks true height, possibly cutting off the true amount of loadable labware. For example, a stack of a ten nest plates with no overlap values for one another might be "naively" assumed to be 15cm, but in reality are only 12cm due to cumulative stacking overlap. In that hypothetical we've "cut off" two extra labwares by over-estimating. The "fix" in this case is to update labware we intend to allow to stack on itself in the stacker, eventually...
|
||
def get_height_of_stacker_labware_pool(self, module_id: str) -> float: | ||
"""Get the overall height of a stack of labware in a Stacker module.""" | ||
stacker = self._modules.get_flex_stacker_substate(module_id) |
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.
Brayans right, probably want to handle the None case for good developer support, since this function is in general geometry. Anything with access to geometry could in theory call it in the future.
Overview
The stacker's stackable labware count is limited by the interior height of the stacker.
This PR adds this property as the
maxStackerFillHeight
in the module definition.The
flex_stacker/fill
andflex_stacker/set_stored_labware
commands are updated to use this property to calculate the actual max labware count based on the height of labware pool.