source: moxy/trunk/src/moxy/model/axis.py @ 835

Last change on this file since 835 was 835, checked in by jemian, 11 years ago

refactoring

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Rev Url
File size: 5.2 KB
Line 
1#!/usr/bin/env python
2
3########### SVN repository information ###################
4# $Date: 2012-04-26 15:54:14 +0000 (Thu, 26 Apr 2012) $
5# $Author: jemian $
6# $Revision: 835 $
7# $URL$
8# $Id: axis.py 835 2012-04-26 15:54:14Z jemian $
9########### SVN repository information ###################
10
11'''
12details about a model single axis
13
14Copyright (c) 2009 - 2011, UChicago Argonne, LLC.
15See LICENSE file for details.
16'''
17
18
19# - - - - - - - - - - - - - - - - - - Imports
20
21
22import m_pv
23import paxis
24
25
26# - - - - - - - - - - - - - - - - - - Global
27
28
29__svnid__ = "$Id: axis.py 835 2012-04-26 15:54:14Z jemian $"
30
31
32# - - - - - - - - - - - - - - - - - - class
33
34class SingleAxis:
35    '''
36    A single axis connects to several EPICS PVs.
37    Since the axis may not be an EPICS motor record,
38    we allow them to be completely separate.
39   
40    :param str name: short name for this axis
41    :param obj axis: Either a Motor object or a PAxis object
42    '''
43   
44    def __init__(self, name, val, isMotorRecord = True,
45                 desc = '', dmov = '', egu = '', rbv = '', stop = ''):
46        '''
47        Constructor
48   
49        :param str name: short name for this axis
50        :param str val: EPICS PV name of the target position of this axis
51        :param bool isMotorRecord: True if val refers to an EPICS motor record
52        :param str rbv: EPICS PV name of the readback position of this axis
53        :param str stop: EPICS PV name of the stop field of this axis, writing 1 to this PV will stop the axis if it is moving
54        :param str dmov: EPICS PV name of the done-moving field of this axis, 1 if axis is not moving, 0 if axis is moving
55        :param str desc: EPICS PV name of the description field of this axis
56        :param str egu: EPICS PV name of the engineering units field of this axis
57        '''
58        self.name = name
59        self.isMotorRecord = isMotorRecord
60        self.axis = None
61        if isMotorRecord:
62            pv = m_pv.GetBasePv(val)
63            if not m_pv.pvIsAvailable(pv, timeout = 0.5):
64                raise Exception, "Could not connect with PV: " + pv
65            if not m_pv.pvIsMotorRec(pv):
66                raise Exception, "%s.RTYP = %s, must be 'motor'" % (pv, m_pv.GetRTYP(pv))
67            self.axis = paxis.Motor(val)
68        else:
69            # elegant, but hard to read, need better feedback if PV not found
70            #status = map(m_pv.pvIsAvailable, (val, rbv, desc, egu, dmov, stop))
71            #ready = reduce(lambda x, y: x and y, status)
72            for pv in (val, rbv, desc, egu, dmov, stop):
73                if not m_pv.pvIsAvailable(pv):
74                    raise Exception, "Could not connect with PV: " + pv
75            self.axis = paxis.PAxis(val, rbv, desc, egu, dmov, stop)
76        if self.axis is None:
77            raise Exception, "Did not connect axis: " + name
78        self.callback_ids = {}
79   
80    def move(self, position):
81        '''tell EPICS to move this axis'''
82        self.axis.VAL = position
83   
84    def stopMotion(self):
85        '''tell EPICS to stop moving this axis'''
86        self.axis.stop()
87   
88    def connect(self, handler = None):
89        '''connect the callbacks'''
90        if len(self.callback_ids) > 0:
91            self.disconnect()
92        for field in ('VAL', 'RBV', 'DESC', 'EGU', 'DMOV', 'STOP'):
93            # remember the callback id
94            cb = self.axis.start_callback(field, handler, {'field': field})
95            self.callback_ids[field] = cb
96        self._connected = True
97   
98    def disconnect(self):
99        '''disconnect all the PVs with EPICS'''
100        for field in self.callback_ids.keys():
101            self.axis.stop_callback(field, self.callback_ids[field])
102        self.callback_ids = {}
103        self._connected = False
104
105
106# - - - - - - - - - - - - - - - - - - methods
107
108
109def __demo_waitmove(axis, position, seconds):
110    '''move this axis and wait for a fixed time (showing EPICS CA monitors)'''
111    from time import sleep
112    print "moving", axis._pvs['VAL'], " to ", position
113    axis.move(position)
114    for i in range(seconds, 0, -1):
115        print i, " seconds remain"
116        sleep(1)
117    print "done waiting"
118
119
120def handler(**kw):
121    '''trivial example callback handler'''
122    print kw['pvname'], kw['field'], kw['value']
123
124
125def _demo_():
126    '''demonstrate use of this module'''
127    from time import sleep
128    pv = "prj:m1"
129   
130    motor = SingleAxis( name = "test axis", val = pv, isMotorRecord = True, )
131    motor.connect(handler=handler)
132    name = motor.axis.DESC
133    motor.axis.DESC = "new name"
134    sleep(1)
135    motor.axis.DESC = name
136    sleep(1)
137
138    # now try a couple moves
139    __demo_waitmove(motor.axis, position=5.5, seconds=5)
140    __demo_waitmove(motor.axis, position=1.1, seconds=5)
141    motor.disconnect()
142    del motor
143
144    # - - - -
145   
146    non_motor = SingleAxis( name = "second axis", isMotorRecord = False, 
147                            val = pv + '.VAL', 
148                            rbv = pv + '.RBV', 
149                            desc = pv + '.DESC', 
150                            egu = pv + '.EGU', 
151                            dmov = pv + '.DMOV', 
152                            stop = pv + '.STOP', 
153                            )
154    non_motor.connect(handler=handler)
155    __demo_waitmove(non_motor.axis, position=5.5, seconds=5)
156    __demo_waitmove(non_motor.axis, position=1.1, seconds=5)
157    non_motor.disconnect()
158
159# - - - - - - - - - - - - - - - - - - main
160
161
162if __name__ == '__main__':
163    _demo_()
Note: See TracBrowser for help on using the repository browser.