APS-4ID-POLAR / ipython-polar

4-ID-Polar ipython configuration for bluesky (and other)
1 stars 3 forks source link

dynamic limit for coordinated theta:2theta motion #20

Open prjemian opened 3 years ago

prjemian commented 3 years ago

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:

Full implementation

Once satisfied with the prototype:

prjemian commented 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.

timmmooney commented 3 years ago

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.

prjemian commented 3 years ago

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.

prjemian commented 3 years ago

The prototype signal is easy to setup. Like this screen except use the proper motor PVs. I'm using from my local IOC.

th_tth_permit_calc

prjemian commented 3 years ago

Also, change the calculation to: (B-A)>=C, the abs is not necessary.

prjemian commented 3 years ago

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)
prjemian commented 3 years ago

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.

prjemian commented 3 years ago

Finished writing the full demo as jupyter notebook: Demo of two-motor dynamic limit signal

prjemian commented 3 years ago

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.

prjemian commented 3 years ago

@CrI3 @gfabbris : What are the specific motor PVs and calculation for the limit?

prjemian commented 3 years ago

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
prjemian commented 3 years ago

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:

Clipboard01

prjemian commented 3 years ago

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)
gfabbris commented 3 years ago

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.

CrI3 commented 3 years ago

th_tth_limit User_calc should work, and the limit has to be like (90-th)-tth>10. Attached shows the current th,tth positions.

prjemian commented 3 years ago

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
gfabbris commented 3 years ago

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.

prjemian commented 3 years ago

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).

gfabbris commented 3 years ago

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):

Screen Shot 2020-09-02 at 7 21 05 PM