DN simplify tecan coordinate system
I changed the coordinate system to match the front of the tecan deck. This will give absolute positioning instead of using off_x and off_y when placing resources. See red line in image for y=0. The resources, however, do not touch this line and are not all the same size, so I am keeping off_y for now.
To make this change, I need to adjust some of the resource dimensions, deck placement, and _liha_positions() function to match this coordinate system.
I also determined the position of the wash station instead of hard coding it so that it can be moved.
This addresses issue: Status: Open. #580
thanks for the PR
given that the tests don't pass, it seems the correction is not applied everywhere consistently. we should be able to generate the same firmware commands given the same inputs. Unless of course, those firmware commands are wrong. But that does not seem likely for positioning.
This will give absolute positioning instead of using off_x and off_y when placing resources.
my understanding is off_x and off_y are used to compute the offset of a resource wrt some default "rail location". changing the coordinate system doesn't help, because it's a per-carrier offset wrt rails that changes.
Perhaps I used "coordinate system" incorrectly. I changed both the placement of carriers on the rails and then the inverse calculation for the y coordinate.
For the placement of carriers, I believe that there was compensation for the values from tecan to make it work. In tecan_decks.py, resources are placed on rails with the following coordinates:
For x, there was not much change, I just adjusted the + 100 to be + 117. This was to compensate for off_x. Most off_x values are within 0.5 to 1 mm. Many are 12.5, which is the center of the rail. Not positive what this is for since every carrier I have is the same size in the x direction.
from this:
(rails - 1) * _RAILS_WIDTH - resource.off_x + 100,
to this:
117 + (rails - 1) * _RAILS_WIDTH,
For y, this was a little more complicated since the original code was using the size of the deck and subtracting the size of the carrier and then adding off_y. This is a very confusing and makes off_y a measurement with respect to the size of the carrier and not a reference point on the deck. If we set 0 as the front edge of the deck (metal), then placement on the deck is just off_y
from this:
resource.off_y + 345 - resource.get_absolute_size_y(),
to this:
resource.off_y,
This then required changing the inverse calculation for y to match the edge of the deck. Not too much of a change.
from this:
y_positions[channel] = int((346.5 - location.y + op.offset.y) * 10) # TODO: verify
to this:
y_positions[channel] = int((352 - (location.y + op.offset.y)) * 10)
I then need to change the resources to match this. I am only using 1000 ul tips and deep well plates at the moment so I only changed 2 resources and the wash station. Perhaps that is why it is failing? Does the test use any specific resources that use the original method of coordinates? I can raise an error for all other carriers that I didn't change.
I also changed the "start" height for picking up a tip since it was adding tip_length before it had a tip and wouldn't pick up a tip. I can remove that if that should be a different PR
i am confused. shifting the origin of the coordinate system would work if every carrier had the same offset, but that is not the case. "Most off_x values are within 0.5 to 1 mm."
For the placement of carriers, I believe that there was compensation for the values from tecan to make it work.
it seems it's not just evoware, it's an actual physical offset
but perhaps i am mistaken and in some weird way it's canceled out by the placement of CarrierSites wrt Carrier lfb. But that seems to be unlikely.
I also changed the "start" height for picking up a tip since it was adding tip_length before it had a tip and wouldn't pick up a tip. I can remove that if that should be a different PR
The original backend was developed on a system with fixed tips. If you need to make changes to make it work with disposable tips, please do! (I like small separate PRs, one for every issue. easy to review and quick to merge)
i am confused. shifting the origin of the coordinate system would work if every carrier had the same offset, but that is not the case. "Most off_x values are within 0.5 to 1 mm."
I see. My thought was that off_x was compensating for incorrect measurements. But perhaps there are carriers with different sizes in the x axis. I can revert that to keep off_x.
we don't know for sure but that seems likely and physically plausible no?
(if you happen to have carriers with different off_{x,y}, could you take a look? :))
as i mentioned in the other post, the way i would solve the off_xy (to get rid of TecanCarrier) is define it in the universal Carrier and set it to 0 for all carriers except the tecan ones where it is defined.
honestly i am not sure what a change to the coordinate system is aiming to accomplish
we don't know for sure but that seems likely and physically plausible no?
(if you happen to have carriers with different off_{x,y}, could you take a look? :))
Hmm. They are different. That is unfortunate and annoying.
as i mentioned in the other post, the way i would solve the off_xy (to get rid of TecanCarrier) is define it in the universal Carrier and set it to 0 for all carriers except the tecan ones where it is defined.
honestly i am not sure what a change to the coordinate system is aiming to accomplish
I was trying to add new resources and there was no logical way to measure the off_y
The carriers are placed using the size of the carrier, which makes off_y reference point variable
resource.off_y + 345 - resource.get_absolute_size_y()
Why does resource.get_absolute_size_y() matter when placing on the deck?
I was trying to add new resources and there was no logical way to measure the off_y
new carriers? for other resources it shouldn't ™ be needed
Why does resource.get_absolute_size_y() matter when placing on the deck?
my interpretation: the carriers always slide all the way back, so the back is their fixed point. in plr coordinates are defined wrt left front bottom (lfb). so: if you have a carrier that is shorter or longer than others but fixed to the back, its y coordinate will change. apparently this is needed for tecan since carriers are not all the same y-size (not the case for hamilton, even though carriers do slide all the way back as all are the same y-size)
new carriers? for other resources it shouldn't ™ be needed
Yes. I meant to say new carriers. Tube and trough carriers.
my interpretation: the carriers always slide all the way back, so the back is their fixed point.
Unfortunately, the carriers neither align at the front nor the back. This makes measuring off_y in physical space inconsistent and confusing. This PR would alleviate that and set a reference point.
front:
back:
in plr coordinates are defined wrt left front bottom (lfb)
Could we reset the coordinate on the machine? left front bottom and reverse the y axis so it lines up with that? These are the commands in tecan
Unfortunately, the carriers neither align at the front nor the back. This makes measuring off_y in physical space inconsistent and confusing. This PR would alleviate that and set a reference point.
ughhh
Could we reset the coordinate on the machine? left front bottom and reverse the y axis so it lines up with that? These are the commands in tecan
wow, I didn't even know this was possible
if we can avoid it, i think we should avoid making modifications to the machine
(is there a way to query this? should we do that on setup and reset to normal? what happens if we change it and someone then uses evoware?)
is off_y this?
because in order to compute the lfb of the carrier, we would need to have a reference to a known point on the deck (if the user passes rails=)
(is there a way to query this? should we do that on setup and reset to normal? what happens if we change it and someone then uses evoware?)
Seems like these commands are not stored long term. They say "this command cannot be stored in non-volatile memory". I am assuming this means if someone restarts the machine, it will reset. But if they dont restart the machine and start using evoware it could be a problem? Not sure what happens during initialization. We could implement this during setup
it would only make this marginally easier (no coordinate system translation in the backend), not worth the risk imo
what we need to fix, at least:
- [ ] wash location (this PR)
- [ ] define what off_y means
- [ ] fix incorrect resource definitions / remove ones without a part number
for the latter 2, do you want to make separate PRs? small PRs are easier to review and merge and look back at later
because in order to compute the lfb of the carrier, we would need to have a reference to a known point on the deck (if the user passes
rails=)
Right. I am not sure where to measure from. Perhaps measure the width from the rail to the edge of the carrier? (red line in the image)
Right. I am not sure where to measure from. Perhaps measure the width from the rail to the edge of the carrier? (red line in the image)
are you able to move a pipette to arbitrary locations? that is often useful for finding out what coordinate system the machine uses :)
in PLR, we can define off_y however we like. it seems the white arrows in my picture above are easily caliper'd
Measuring off_y from the front of the deck is easiest. Especially if the carrier is covering the rails (see trough). off_x is more difficult to measure. Any ideas? Perhaps take the width of the carrier and divide by width of rail (25) and take the remainder?
Measuring off_y from the front of the deck is easiest. Especially if the carrier is covering the rails (see trough). off_x is more difficult to measure. Any ideas? Perhaps take the width of the carrier and divide by width of rail (25) and take the remainder?
resources should be able to be defined "in isolation" meaning without considering external objects.
considering the 'holes' are in fixed spots wrt lfb of its carrier (of course different between different carriers), and the 'nobs' are fixed on the robot ("rails"), if we define both locations as such, we can compute the lfb of the carrier -> from there the location of the sites and ultimately the labware.
(of course in terms of calipering, you could measure wrt front of the robot and then calculate based on knowledge of nob spacing)
considering the 'holes' are in fixed spots wrt lfb of its carrier (of course different between different carriers), and the 'nobs' are fixed on the robot ("
rails"), if we define both locations as such, we can compute the lfb of the carrier -> from there the location of the sites and ultimately the labware.
Sounds good. I can define lfb based on the 'nobs'. Would the off_y be a negative number with respect to the 'nobs'?
Should this be off_x (in the image)? Currently for this tip carrier it is set to 12mm which I can't figure out what that measurement is. I can also just leave off_x as is.
Sounds good. I can define lfb based on the 'nobs'. Would the off_y be a negative number with respect to the 'nobs'?
Let' make it positive, "distance".
(the carrier should symmetrical (right??), but otherwise measure from the carrier lfb to the 'lfb of the hole')
Currently for this tip carrier it is set to 12mm
Possibly to the center of the nob?
We're gonna need to figure out how to convert nob index + off_x -> x coordinate