Документ взят из кэша поисковой машины. Адрес оригинального документа : http://www.apo.nmsu.edu/Telescopes/TCC/html/check_pos_8py_source.html
Дата изменения: Tue Sep 15 02:25:37 2015
Дата индексирования: Sun Apr 10 01:33:44 2016
Кодировка:

Поисковые слова: п п п п п п
lsst.tcc: python/tcc/mov/checkPos.py Source File
lsst.tcc  1.2.2-3-g89ecb63
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
checkPos.py
Go to the documentation of this file.
1 from __future__ import division, absolute_import
2 
3 import numpy
4 import coordConv
5 
6 import tcc.base
7 
8 __all__ = ["checkPos"]
9 
10 def checkPos(pos, minPos, maxPos, nearPos, wrapPref, doWrap):
11  """Apply wrap preference and verify that position is in bounds
12 
13  @param[in] pos position, wrap unknown
14  @param[in] minPos minimum allowed position
15  @param[in] maxPos maximum allowed position
16  @param[in] nearPos nearby angle (the reference for near wrap or doWrap)
17  @param[in] doWrap:
18  if true (slewing): use wrapPref and unwrap as desired, avoiding limits
19  if false (tracking): ignore wrapPref and only wrap near, even if out of bounds
20  @param[in] wrapPref wrap preference; ignored if doWrap false
21  @return two items:
22  - outPos: wrapped position, or nan if errCode not AxisErr_OK
23  - errCode: one of:
24  - AxisErr_OK if no error
25  - AxisErr_MinPos if pos < minPos
26  - AxisErr_MaxPos if pos > maxPos
27  - AxisErr_CannotCompute if wrapPref = None and nearPos is not finite
28 
29  @throw RuntimeError if wrapPref unknown (if doWrap true)
30 
31  @warning: If the limits of motion span a range greater than 720 degrees,
32  this routine will not use the excess, unless doWrap false or wrapPref is "near".
33  See "details" for more information about the ranges used.
34 
35  Details:
36  The limits minPos and maxPos are inclusive, meaning
37  outPos may equal either limit and still be in bounds.
38 
39  The following ranges are used:
40  Wrap Preference Range
41  doWrap false [nearPos - 180, nearPos + 180)
42  WrapType_None no change; outPos = pos
43 
44  Ideal Range (may be adjusted to avoid limits)
45  WrapType_Nearest [nearPos - 180, nearPos + 180)
46  WrapType_Negative [meanPos - 360, meanPos)
47  WrapType_Middle [meanPos - 180, meanPos + 180)
48  WrapType_Positive [meanPos, meanPos + 360)
49 
50  where:
51  - meanPos = (minPos + maxPos) / 2
52  - [,) means the lower limit is inclusive and the upper exclusive.
53  - Ideal Range means the range if limits are not an issue.
54  If the upper end is out of bounds, both ends are decreased.
55  Then if the lower end is out of bounds, both ends are increased.
56  Then the position is wrapped and range checked.
57 
58  The main equation:
59  Given an angle X and a range [A, A + 360),
60  the angle WrapX = X wrapped into the given range is given by:
61  WrapX = Y, if Y >= A, Y + 360 otherwise,
62  where
63  Y = ((X - A) mod 360) + A
64  and "mod" is the mathematical modulo function,
65  which is similar to the FORTRAN MOD function except that
66  S mod T is always in the range [0, T) (T > 0)
67  """
68  # default outputs
69  outPos = pos
70  errCode = tcc.base.AxisErr_OK
71 
72  if not numpy.isfinite(pos):
73  return (pos, tcc.base.AxisErr_CannotCompute)
74 
75  # handle NoUnwrap and None cases
76  if (not doWrap) or (wrapPref == tcc.base.WrapType_None):
77  # do not wrap; either wrap to nearest or accept position "as is"
78  if doWrap:
79  # wrapPref is None; accept position "as is"
80  outPos = pos
81  else:
82  # tracking: wrap to nearest, even if going out of bounds
83  outPos = coordConv.wrapNear(pos, nearPos)
84 
85  if outPos < minPos:
86  errCode = tcc.base.AxisErr_MinPos
87  elif outPos > maxPos:
88  errCode = tcc.base.AxisErr_MaxPos
89 
90  else:
91  # apply wrap preference; avoid hitting the limits if possible
92  # compute wrapMin: the ideal minimum angle of the wrap range
93  meanPos = (minPos + maxPos) / 2.0
94  if wrapPref == tcc.base.WrapType_Nearest:
95  wrapMin = nearPos - 180.0
96  elif wrapPref == tcc.base.WrapType_Negative:
97  wrapMin = meanPos - 360.0
98  elif wrapPref == tcc.base.WrapType_Middle:
99  wrapMin = meanPos - 180.0
100  elif wrapPref == tcc.base.WrapType_Positive:
101  wrapMin = meanPos
102  else:
103  raise RuntimeError("Unknown wrap preference %s" % (wrapPref,))
104 
105  if not numpy.isfinite(wrapMin):
106  return (coordConv.DoubleNaN, tcc.base.AxisErr_CannotCompute)
107 
108  # Adjust the minimum of the wrap range for the limits, if necessary:
109  # If the upper end is out of bounds, decrease the lower end
110  # to maxPos - 360, to preserve a full 360 deg of motion.
111  # Then if the lower end is out of bounds, increase it to minPos.
112  # After adjustment, the minimum (wrapMin) is guranteed >= minPos,
113  # but the maximum (wrapMin + 360) is NOT guranteed <= maxPos.
114  wrapMin = min(wrapMin, maxPos - 360.0)
115  wrapMin = max(wrapMin, minPos)
116 
117  # put the angle into the wrap range, which is [wrapMin, wrapMin + 360)
118  diffMod360 = (pos - wrapMin) % 360.0
119  if diffMod360 < 0.0:
120  diffMod360 = diffMod360 + 360.0
121 
122  outPos = diffMod360 + wrapMin
123 
124  # if the resulting angle is too large,
125  # we cannot find a wrap that is in range
126  # set output position = input position and set errCode accordingly
127  if outPos > maxPos:
128  outPos = pos
129  if outPos < minPos:
130  errCode = tcc.base.AxisErr_MinPos
131  else:
132  errCode = tcc.base.AxisErr_MaxPos
133 
134  if errCode != tcc.base.AxisErr_OK:
135  outPos = float("nan")
136 
137  return (outPos, errCode)