Skip to content

Commit

Permalink
MNT #530 Should this class update target value?
Browse files Browse the repository at this point in the history
  • Loading branch information
prjemian committed Oct 5, 2021
1 parent 0241ba8 commit c760d6f
Showing 1 changed file with 25 additions and 13 deletions.
38 changes: 25 additions & 13 deletions apstools/_devices/positioner_soft_done.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,18 @@ class PVPositionerSoftDone(PVPositioner):
Override (in subclass) with `EpicsSignal` to connect with a PV.
In some controllers (such as temperature controllers),
the setpoint may be changed incrementally
towards this target value (such as a ramp or controlled trajectory).
In such cases, the ``target`` will be final value while ``setpoint``
will be the current desired position.
In some controllers (such as temperature controllers), the setpoint
may be changed incrementally towards this target value (such as a
ramp or controlled trajectory). In such cases, the ``target`` will
be final value while ``setpoint`` will be the current desired position.
Otherwise, both ``setpoint`` and ``target`` will be set to the same value.
update_target : bool
``True`` when this object update the ``target`` Component directly.
Use ``False`` if the ``target`` Component will be updated externally,
such as by the controller when ``target`` is an ``EpicsSignal``.
(new in apstools 1.5.2)
(new in apstools 1.5.3)
"""

# positioner
Expand All @@ -94,6 +97,10 @@ def precision(self):
def cb_readback(self, *args, **kwargs):
"""
Called when readback changes (EPICS CA monitor event).
Computes if the positioner is done moving::
done = |readback - setpoint| <= tolerance
"""
diff = self.readback.get() - self.setpoint.get()
_tolerance = (
Expand All @@ -109,10 +116,12 @@ def cb_readback(self, *args, **kwargs):
def cb_setpoint(self, *args, **kwargs):
"""
Called when setpoint changes (EPICS CA monitor event).
When the setpoint is changed, force done=False. For any move,
done must go != done_value, then back to done_value (True).
When the setpoint is changed, force done=False. For any move, done
**must** transition to ``!= done_value``, then back to ``done_value``.
Without this response, a small move (within tolerance) will not return.
Next update of readback will compute self.done.
Next update of readback will compute ``self.done``.
"""
self.done.put(not self.done_value)

Expand All @@ -123,6 +132,7 @@ def __init__(
readback_pv="",
setpoint_pv="",
tolerance=None,
update_target=True,
**kwargs,
):

Expand All @@ -134,6 +144,7 @@ def __init__(
# Make the default alias for the readback the name of the
# positioner itself as in EpicsMotor.
self.readback.name = self.name
self.update_target = update_target

self.readback.subscribe(self.cb_readback)
self.setpoint.subscribe(self.cb_setpoint)
Expand All @@ -143,10 +154,11 @@ def __init__(
def _setup_move(self, position):
"""Move and do not wait until motion is complete (asynchronous)"""
self.log.debug("%s.setpoint = %s", self.name, position)
kwargs = {}
if issubclass(self.target.__class__, EpicsSignalBase):
kwargs["wait"] = True # Signal.put() warns if kwargs are given
self.target.put(position, **kwargs)
if self.update_target:
kwargs = {}
if issubclass(self.target.__class__, EpicsSignalBase):
kwargs["wait"] = True # Signal.put() warns if kwargs are given
self.target.put(position, **kwargs)
self.setpoint.put(position, wait=True)
if self.actuate is not None:
self.log.debug("%s.actuate = %s", self.name, self.actuate_value)
Expand Down

0 comments on commit c760d6f

Please sign in to comment.