1 from __future__
import division, absolute_import
5 from RO.StringUtil
import strFromException
9 from .showObject
import showObjectFields
10 from tcc.msg import formatAxisCmdStateAndErr, moveItemKW
12 __all__ = [
"startSlew"]
14 def startSlew(tccActor, obj, slewCmd, doAbsRefCorr, doCollimate, minEndTime=0):
15 """Start a slew to the position specified in obj
17 Before calling, be sure to update obj as you like, applying wrap preferences
18 and doRestart such that obj.targetMount is as desired. StartSlew ignores wrap preferences
19 and will not slew axes whose targetMount is invalid.
20 Axes that exist and are not to be slewed are commanded to halt.
22 This happens in three stages:
23 - Send the DRIFT command the appropriate axis controllers
25 - Send the slew to the appropriate axis controllers
27 @param[in,out] tccActor tcc actor with old obj block
28 obj block is replaced by obj
29 @param[in,out] obj new object block
30 @param[in,out] slewCmd new slew command
31 @param[in] doAbsRefCorr apply absolute fiducial corrections during this slew?
32 @param[in] doCollimate trigger a collimation update (based on destination altitude)?
33 @param[in] minEndTime minimum end time (TAI, MJD sec); 0 means no minimum
35 tccActor.collimateSlewEndTimer.cancel()
36 if not tccActor.slewCmd.isDone:
37 tccActor.slewCmd.setState(tccActor.slewCmd.Done,
"SlewSuperseded")
39 tccActor.slewCmd = slewCmd
40 doDrift = [pvt.isfinite()
or cmdState == tcc.base.AxisState_Halting \
41 for pvt, cmdState
in itertools.izip(obj.targetMount, obj.axisCmdState)]
43 tccActor.writeToUsers(
"i",
"Text=\"Nothing to do: all axes halted\"", cmd=slewCmd)
44 tccActor.axisDevSet.stop(userCmd=slewCmd)
47 def driftCallback(driftCmd):
48 """Callback for drift command
50 If drift succeeds for all axes then compute and start the slew,
51 else initialize all axes (to make sure no drifting axes are left drifting).
55 if not tccActor.slewCmd.isDone:
56 tccActor.slewCmd.setState(tccActor.slewCmd.Failed,
57 textMsg =
"Slew failed: %s" % (driftCmd.getMsg(),))
60 for i, doit
in enumerate(doDrift):
62 tccActor.obj.axisCmdState[i] = tcc.base.AxisState_Drifting
64 tccActor.writeToUsers(msgCode, msgStr, cmd=tccActor.slewCmd)
67 doAbsRefCorr=doAbsRefCorr,
68 doCollimate=doCollimate,
69 minEndTime=minEndTime,
73 tccActor.trackTimer.cancel()
74 driftCmd = tccActor.axisDevSet.drift()
75 driftCmd.addCallback(driftCallback)
78 def _computeAndSendSlew(tccActor, doAbsRefCorr, doCollimate, minEndTime=0):
79 """Compute a slew and initiate it by sending PVTs to the axis controllers.
81 Call after updating tccActor.obj as you like, and causing the axes you want slewed
82 or halted to DRIFT (and updating obj.axisCmdState and obj.actMount accordingly).
83 See tcc.axis.computeSlew for details on what you must do.
84 Axes that exist and are not to be slewed are commanded to halt.
86 @param[in,out] tccActor tcc actor
87 obj block is updated; see tcc.axis.computeSlew for details
88 many other blocks are read
89 @param[in] doAbsRefCorr apply absolute fiducial corrections during this slew?
90 @param[in] minEndTime minimum end time (TAI, MJD sec); 0 means no minimum
93 slewCmd = tccActor.slewCmd
96 minEndTime=minEndTime,
100 telMod=tccActor.telMod,
101 axeLim=tccActor.axeLim,
105 def axisSlewCallback(axisCmd, tccActor=tccActor, slewData=slewData):
106 """Callback for axisDevSet.startSlew
109 tccActor.writeToUsers(msgCode, msgStr, cmd=tccActor.slewCmd)
115 slewCmd.setState(slewCmd.Failed, textMsg =
"Slew failed: %s" % (axisCmd.getMsg(),))
118 slewDuration = tccActor.obj.slewEndTime - tcc.base.tai()
119 msgStr =
"SlewBeg=%0.2f; SlewDuration=%0.2f; SlewNumIter=%s; %s" % \
120 (tccActor.obj.slewEndTime, slewDuration, slewData.numIter,
moveItemKW(tccActor.obj))
121 tccActor.writeToUsers(
">", msgStr, cmd=slewCmd)
122 tccActor.slewDoneTimer.start(slewDuration, _reportSlewDone, tccActor, slewCmd)
124 tccActor.trackTimer.start(0., callFunc=tccActor.updateTracking)
126 tccActor.updateCollimation()
127 if tccActor.tune.collimateSlewEnd >= 0:
128 collWaitTime = slewDuration - tccActor.tune.collimateSlewEnd
130 tccActor.collimateSlewEndTimer.start(collWaitTime, tccActor.updateCollimation)
133 axisCmd = tccActor.axisDevSet.startSlew(slewData.pathList, doAbsRefCorr=doAbsRefCorr)
134 axisCmd.addCallback(axisSlewCallback)
136 except Exception
as e:
138 slewCmd.setState(slewCmd.Failed, textMsg=
"Could not start the slew: %s; initializing all axes" % \
139 strFromException(e),)
140 tccActor.axisDevSet.init()
146 def _reportSlewDone(tccActor, slewCmd):
147 """Report completion of slew (if slew command is still active)
149 @param[in] slewCmd user's track, offset or rotate command
151 @warning: do not get slewCmd from tccActor, since it may change; it is crucial
152 to have the original slew command.
158 for axis
in range(tcc.base.NAxes):
159 if tccActor.obj.axisCmdState[axis] == tcc.base.AxisState_Slewing:
160 tccActor.obj.axisCmdState[axis] = tcc.base.AxisState_Tracking
161 elif tccActor.obj.axisCmdState[axis] == tcc.base.AxisState_Halting:
162 tccActor.obj.axisCmdState[axis] = tcc.base.AxisState_Halted
163 stopSlotSet.append(tccActor.axisDevSet.slotFromIndex(axis))
166 tccActor.writeToUsers(msgCode, msgStr, cmd=tccActor.slewCmd)
168 slewCmd.setState(slewCmd.Done, hubMsg=
"SlewEnd")
174 tccActor.axisDevSet.init(slotList=stopSlotSet)
def computeSlew
Compute a slew to a given user-specified position, by iteration.
def showObjectFields
Write fields from the object block.