-
Notifications
You must be signed in to change notification settings - Fork 0
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
Add services for Thorlabs motors using Kinesis #200
Conversation
fe5c7e1
to
075555c
Compare
@raphaelpclt could you provide a first review on this? Some of the hardware tests are outstanding but only as additional iterations. |
I went to the lab to perform tests. I run the following tests on each motor (one KDC and one TDC):
Then, I performed tests with the two motors linked to the PC (the TDC and the KDC). All the tests we wanted to do on both motors with the service are done and successful. |
89d92be
to
f0a412c
Compare
@ehpor @raphaelpclt if any of you have some time to review this in the coming time, the PR is ready for 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.
It looks good, with a few minor questions.
catkit2/services/thorlabs_cube_motor_kinesis/thorlabs_cube_motor_kinesis.py
Outdated
Show resolved
Hide resolved
catkit2/services/thorlabs_cube_motor_kinesis/thorlabs_cube_motor_kinesis.py
Show resolved
Hide resolved
self.log.debug("Current position: %f %s", real_unit.value, self.unit) | ||
self.current_position.submit_data(np.array([real_unit.value], dtype='float64')) | ||
|
||
def wait_for_completion(self): |
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.
wait_for_completion
is only used in the homing function. Don't you want to use it in set_current_position
too?
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.
The motor itself behaves differently when homing and when moving position, which is why we didn't block it with this wait when it's just changing position. Let me remind myself of the details and then either justify our choice or follow your advice and put it in there as well.
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.
Ok this one is tricky. If we do not wait for completion in the set_current_position()
, it intercepts the first command and executes the second command instead, and correctly. So I am fine with this behavior and don't want to add the wait_for_completion there.
However, the method get_current_position()
gets called too early and puts an intermediate position on the current_position data stream, which the device reads while it is moving. Which is obviously not at all what we want.
We then tried adding the wait_for_completion()
anyway, to fix the wrong values on the data stream, but in this case it just finishes running the first command. Data stream value is still wrong. And it puts command 2 in a cache apparently and runs it before the next command that is sent to the motor... also not the behavior we want, so I still vote against adding the wait_for_completion()
in set_current_position()
.
Since this was so weird, we checked the data stream values after calling home()
a couple of times and this is always fine, so it's something about the command data stream monitoring and getting the real device position before the device stops moving.
I don't actually understand what wait_for_completion()
does. @a-sevin, maybe you can help out with this conundrum? What does it do and what are the values for message_id
and message_type
it checks against?
The minimum requirement for this fix is that the correct (final) value is put on the current_position data stream after the movement concludes.
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.
Maybe I should just regularly update the current position, like the Newport XPS service?
while not self.should_shut_down: |
@raphaelpclt what do you think about this?
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'm reading the tutorial labview which is not so bad. I need to check what to use it in Python:
https://www.thorlabs.com/Software/Motion%20Control/Kinesis/Kinesis-labview.pdf
This wait_for_completion()
could be very simple: wait the get_current_position()
stable...
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.
For the get_current_position
, yes I think the solution with the newport xps is what you want. Then I am not sure of what you want for the moving behavior. The fact that the moving function returns before completion sounds a bit weird to me, but maybe not dramatic.
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.
Considering we now get correct values on the current_position data stream within the time scales we need (1 s), I will open a follow-up issue to look into a more rigorous handling of the data stream update inside of set_current_position()
.
Issue: #206
catkit2/services/thorlabs_cube_motor_kinesis_sim/thorlabs_cube_motor_kinesis_sim.py
Show resolved
Hide resolved
if self.min_position_config <= position <= self.max_position_config: | ||
self.testbed.simulator.move_stage(stage_id=self.id, | ||
old_position=self.get_current_position(), | ||
new_position=position) | ||
else: | ||
self.log.warning('Motor not moving since commanded position is outside of configured range.') | ||
self.log.warning('Position limits: %f %s <= position <= %f %s.', | ||
self.min_position_config, self.unit, self.max_position_config, self.unit) |
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.
Unless I miss something, the self.current_position
datastream is initialized in open
, but never updated. I guess it would have to be update in set_current_position
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.
Huh, you're raising a good point here. This is actually not a bug - the self.current_position
data stream gets updated in the simulator service script of our thd2 simulator, much like hicat2's (both in external repos), so we're safe, every time the simulator is called to set the simulated motor position, the data stream is updated as well.
Now, why the choice has been originally done to do it this way, I don't know. I also agree that it would be more logical to update the data stream in the simulated service's set_current_position
as is done in the hardware service. Maybe a new issue to open and to discuss?
catkit2/services/thorlabs_cube_motor_kinesis_sim/thorlabs_cube_motor_kinesis_sim.py
Outdated
Show resolved
Hide resolved
I now spun off the command monitoring on a thread and update the current position in regular updates in the main(). Works fine in simulation although I didn't check the data streams, which we'll do on hardware - @erinpougheon this can be retested on hardware, where we have to make sure that both |
I just went to the lab to test the changes on hardware. |
ca1d404
to
c60f305
Compare
@raphaelpclt we are getting the expected behavior now so this is ready for a new review. I opened a follow-up issue for a closer look into the data stream synchronization with the motor move (#206). |
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 good!
Taking over from #170. Fixes #169. See #169 (comment) for details.
Credit for writing the hardware service goes entirely to @a-sevin.
Todo before review