Open prjemian opened 3 years ago
Not happy with the prototype so far. The permit calculation works but identifies not permitted transients in test cases where motion is expected to succeed. Since we want the permit calculation to do exactly that, the problem to fix is how Bluesky should handle the situation. Seems as if we need a custom Suspender or a more judicious selection of when to apply the suspender.
Hi Pete,
I tried to look at the prototype, but I can't find the userCalc you're talking about. I looked in 4id and 4idd.
Tim Mooney (mooney@anl.gov) (630)252-5417 Beamline Controls Group (www.aps.anl.gov) Advanced Photon Source, Argonne National Lab
From: Pete R Jemian notifications@github.com Sent: Tuesday, September 1, 2020 3:12 PM To: APS-4ID-POLAR/ipython-polar ipython-polar@noreply.github.com Cc: Mooney, Tim M. mooney@anl.gov; Mention mention@noreply.github.com Subject: Re: [APS-4ID-POLAR/ipython-polar] dynamic limit for coordinated theta:2theta motion (#20)
Not happy with the prototype so far. The permit calculation works but identifies not permitted transients in test cases where motion is expected to succeed. Since we want the permit calculation to do exactly that, the problem to fix is how Bluesky should handle the situation. Seems as if we need a custom Suspender or a more judicious selection of when to apply the suspender.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/APS-4ID-POLAR/ipython-polar/issues/20#issuecomment-685105319, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ABT6PF2ER4AHREXKBHB7U2DSDVISNANCNFSM4QQ7FBGQ.
I'm working it up offline, not at the beamline.
The problem with the suspender I used is that when the boolean goes low, bluesky sends a stop to the motors and so the momentary dynamic limit compromise is latched. A custom suspender should avoid that.
The prototype signal is easy to setup. Like this screen except use the proper motor PVs. I'm using from my local IOC.
Also, change the calculation to: (B-A)>=C
, the abs
is not necessary.
Here is where bluesky tells the motors to stop:
if justification is not None:
print("Justification for this suspension:\n%s" % justification)
for current_run in self._run_bundlers.values():
current_run.record_interruption('resume')
# During suspend, all motors should be stopped. Call stop() on
# every object we ever set().
self._stop_movable_objects(success=True)
The summary is that bluesky suspenders will STOP all motors under operation by the RunEngine at the time. A custom suspender would not affect this basic action. Users should avoid this or face the task of walking the motors out of the permit problem.
Finished writing the full demo as jupyter notebook: Demo of two-motor dynamic limit signal
Worked up the prototype in an offline IOC so as to not interfere with existing configurations. The conclusion from the demo:
We can avoid an anticipated collision of instrument hardware by providing a RunEngine suspender tied to the value of an EPICS PV.
When the suspender detects a limit violation, it sends a stop to each of the motors controlled by the scan.
Is this the action we want? Maybe need to test this prototype on the beamline th:tth motors next before proceeding.
@CrI3 @gfabbris : What are the specific motor PVs and calculation for the limit?
Perhaps these?
devices/spec_config.py:# th = EpicsMotor('4iddx:m65', name='th', labels=('motor',)) # 4C Theta
devices/spec_config.py:# tth = EpicsMotor('4iddx:m66', name='tth', labels=('motor',)) # 4C Two Theta
motor | PV | ophyd object |
---|---|---|
theta | 4iddx:m65 |
huber.th |
2theta | 4iddx:m66 |
huber.tth |
opened caQtDM screen:
pushd /net/s4dserv/xorApps/epics/synApps_5_6/ioc/4id
start_caQtDM_4iddx
Then opened userCalcs, pressed Enable
on the main screen, then picked 4iddx:userCalc1
since it appears not already in use. Configured per example notebook as shown here:
Looks like the local bluesky instrument profile has not been updated from github yet. Should be easy to interface as RunEngine suspender. I suggest adding this into instrument/devices/huber.py
:
# add these imports
from bluesky.suspenders import SuspendBoolLow
from ophyd import EpicsSignal
from ..framework import RE
# add to the `Diffractometer` Device:
th_tth_min = Component(EpicsSignal, "userCalc1.C", labels=('diffractometer', 'limits'))
th_tth_permit = Component(EpicsSignal, "userCalc1.VAL", labels=('diffractometer', 'limits'))
# add after this line: huber = Diffra...
sus = SuspendBoolLow(huber.th_tth_permit)
RE.install_suspender(sus)
You found the correct motors.
I'm actually using Bluesky at 4-ID-D today (to control temperature). I think the instrument profile at the Beamline should be close to the last version from GitHub, I think I last updated it on Monday.
I will try to test this today. I'll at least turn on the motors, so we can test remotely if needed.
User_calc should work, and the limit has to be like (90-th)-tth>10. Attached shows the current th,tth positions.
Can you update the userCalc then? I believe these are the changes to make. Enter them from the Linux console (not a bluesky console):
caput 4iddx:userCalc1.CALC "((90-A)-B)>C"
caput 4iddx:userCalc1.C 10
I changed the userCalc and that is working as it should. I found that our tolerance is actually ~28 degrees, but for now I'll leave it as 50 degrees just for testing. I should be able to try it with bluesky later today.
Keep in mind that it is only a calculation now. The userCalc does not stop anything. Once you implement the Bluesky suspender, the suspender will stop motors, when the RunEngine runs a scan. It still won't stop the ipython command line movement of th or tth. That action would come from integrating this into the IOC (and having the calculation propagate into pressing the STOP button on these motors).
I implemented this in #23, it works just as @prjemian described. Note that the math for the check should be ((90+A)-B)>=C because the problem theta and two theta move in the same direction. I noticed that there is ~0.16 degrees that the motor moves extra. I'm guessing this is related to the time it takes to process the issue and hit stop.
Below is an example of it in action (I kept moving theta to get it out of suspension):
Need to create a dynamic limit to protect against collision of theta & 2theta axes during coordinated motion. Discussed today with @timmmooney & @keenanlang. Joint decision was to use one of the userCalcs to prototype this calculation. Once satisfied, a custom database (including calculation, motion stop, ...) will be created in the IOC so that users do not accidentally break this new protection.
The coordinated motion of these two axes is sufficiently slow that a motion STOP could be implemented in a calculation record in the IOC.
Prototype
The prototype would first check the validity of watching RBV from both axes and making sure they are no closer than a user-defined constant. If the axes are too close (say within 5 degrees) , the Bluesky RunEngine will be suspended. These steps are needed for the prototype:
ophyd.EpicsSignal
Full implementation
Once satisfied with the prototype: