API
kTracker.hpp
Go to the documentation of this file.
1 /** \file kTracker.hpp
2  * \brief The MagAO-X K-mirror rotation tracker header file
3  *
4  * \ingroup kTracker_files
5  */
6 
7 #ifndef kTracker_hpp
8 #define kTracker_hpp
9 
10 
11 #include "../../libMagAOX/libMagAOX.hpp" //Note this is included on command line to trigger pch
12 #include "../../magaox_git_version.h"
13 
14 #include <mx/math/gslInterpolation.hpp>
15 #include <mx/ioutils/readColumns.hpp>
16 
17 /** \defgroup kTracker
18  * \brief The MagAO-X application to track pupil rotation with the k-mirror.
19  *
20  * <a href="../handbook/operating/software/apps/kTracker.html">Application Documentation</a>
21  *
22  * \ingroup apps
23  *
24  */
25 
26 /** \defgroup kTracker_files
27  * \ingroup kTracker
28  */
29 
30 namespace MagAOX
31 {
32 namespace app
33 {
34 
35 /// The MagAO-X ADC Tracker
36 /**
37  * \ingroup kTracker
38  */
39 class kTracker : public MagAOXApp<true>
40 {
41 
42  //Give the test harness access.
43  friend class kTracker_test;
44 
45 protected:
46 
47  /** \name Configurable Parameters
48  *@{
49  */
50 
51 
52  float m_zero {0}; ///< The starting point for the K-mirorr at zd=0.
53 
54  int m_sign {1}; ///< The sign to apply to the zd to rotate the k-mirror
55 
56  std::string m_devName {"stagek"}; ///< The device name of the K-mirror stage. Default is 'stagek'
57  std::string m_tcsDevName {"tcsi"}; ///< The device name of the TCS Interface providing 'teldata.zd'. Default is 'tcsi'
58 
59  float m_updateInterval {10};
60 
61  ///@}
62 
63  bool m_tracking {false}; ///< The interval at which to update positions, in seconds. Default is 10 secs.
64 
65  float m_zd {0};
66 
67 public:
68  /// Default c'tor.
69  kTracker();
70 
71  /// D'tor, declared and defined for noexcept.
72  ~kTracker() noexcept
73  {}
74 
75  virtual void setupConfig();
76 
77  /// Implementation of loadConfig logic, separated for testing.
78  /** This is called by loadConfig().
79  */
80  int loadConfigImpl( mx::app::appConfigurator & _config /**< [in] an application configuration from which to load values*/);
81 
82  virtual void loadConfig();
83 
84  /// Startup function
85  /**
86  *
87  */
88  virtual int appStartup();
89 
90  /// Implementation of the FSM for kTracker.
91  /**
92  * \returns 0 on no critical error
93  * \returns -1 on an error requiring shutdown
94  */
95  virtual int appLogic();
96 
97  /// Shutdown the app.
98  /**
99  *
100  */
101  virtual int appShutdown();
102 
103 
104  /** @name INDI
105  *
106  * @{
107  */
108 protected:
109 
110  pcf::IndiProperty m_indiP_tracking;
111 
112  pcf::IndiProperty m_indiP_teldata;
113 
114 
115  pcf::IndiProperty m_indiP_kpos;
116 
117 public:
119 
120 
122 
123 
124 
125  ///@}
126 };
127 
128 kTracker::kTracker() : MagAOXApp(MAGAOX_CURRENT_SHA1, MAGAOX_REPO_MODIFIED)
129 {
130 
131  return;
132 }
133 
135 {
136  config.add("k.zero", "", "k.zero", argType::Required, "k", "zero", false, "float", "The k-mirror zero position. Default is -40.0.");
137 
138  config.add("k.sign", "", "k.sign", argType::Required, "k", "sign", false, "int", "The k-mirror rotation sign. Default is +1.");
139 
140 
141 
142  config.add("k.devName", "", "k.devName", argType::Required, "k", "devName", false, "string", "The device name of the k-mirrorstage. Default is 'stagek'");
143 
144  config.add("tcs.devName", "", "tcs.devName", argType::Required, "tcs", "devName", false, "string", "The device name of the TCS Interface providing 'teldata.zd'. Default is 'tcsi'");
145 
146  config.add("tracking.updateInterval", "", "tracking.updateInterval", argType::Required, "tracking", "updateInterval", false, "float", "The interval at which to update positions, in seconds. Default is 10 secs.");
147 }
148 
149 int kTracker::loadConfigImpl( mx::app::appConfigurator & _config )
150 {
151  _config(m_zero, "k.zero");
152  _config(m_sign, "k.sign");
153  _config(m_devName, "k.devName");
154 
155  _config(m_tcsDevName, "tcs.devName");
156 
157  _config(m_updateInterval, "tracking.updateInterval");
158 
159  return 0;
160 }
161 
163 {
164  loadConfigImpl(config);
165 }
166 
168 {
169 
170 
173 
174 
176 
177  m_indiP_kpos = pcf::IndiProperty(pcf::IndiProperty::Number);
178  m_indiP_kpos.setDevice(m_devName);
179  m_indiP_kpos.setName("position");
180  m_indiP_kpos.add(pcf::IndiElement("target"));
181 
183 
184  return 0;
185 }
186 
188 {
189 
190  static double lastupdate = 0;
191 
192  if(m_tracking && mx::sys::get_curr_time() - lastupdate > m_updateInterval)
193  {
194  float k = m_zero + m_sign*0.5*m_zd;
195 
196  std::cerr << "Sending k-mirror to: " << k << "\n";
197 
198  m_indiP_kpos["target"] = k;
200 
201  lastupdate = mx::sys::get_curr_time();
202 
203 
204  }
205  else if(!m_tracking) lastupdate = 0;
206 
207  return 0;
208 }
209 
211 {
212  return 0;
213 }
214 
215 INDI_NEWCALLBACK_DEFN(kTracker, m_indiP_tracking)(const pcf::IndiProperty &ipRecv)
216 {
217  if(ipRecv.getName() != m_indiP_tracking.getName())
218  {
219  log<software_error>({__FILE__,__LINE__, "wrong INDI property received."});
220  return -1;
221  }
222 
223  if(!ipRecv.find("toggle")) return 0;
224 
225  if( ipRecv["toggle"].getSwitchState() == pcf::IndiElement::On)
226  {
227  updateSwitchIfChanged(m_indiP_tracking, "toggle", pcf::IndiElement::On, INDI_IDLE);
228 
229  m_tracking = true;
230 
231  log<text_log>("started ADC rotation tracking");
232  }
233  else
234  {
235  updateSwitchIfChanged(m_indiP_tracking, "toggle", pcf::IndiElement::Off, INDI_IDLE);
236 
237  m_tracking = false;
238 
239  log<text_log>("stopped ADC rotation tracking");
240  }
241 
242  return 0;
243 }
244 
245 
246 INDI_SETCALLBACK_DEFN(kTracker, m_indiP_teldata)(const pcf::IndiProperty &ipRecv)
247 {
248  if(ipRecv.getName() != m_indiP_teldata.getName())
249  {
250  log<software_error>({__FILE__,__LINE__,"wrong INDI property received"});
251 
252  return -1;
253  }
254 
255  if(!ipRecv.find("zd")) return 0;
256 
257  m_zd = ipRecv["zd"].get<float>();
258 
259  return 0;
260 }
261 
262 } //namespace app
263 } //namespace MagAOX
264 
265 #endif //kTracker_hpp
266 
The base-class for MagAO-X applications.
Definition: MagAOXApp.hpp:75
stateCodes::stateCodeT state()
Get the current state code.
Definition: MagAOXApp.hpp:2082
int registerIndiPropertyNew(pcf::IndiProperty &prop, int(*)(void *, const pcf::IndiProperty &))
Register an INDI property which is exposed for others to request a New Property for.
int createStandardIndiToggleSw(pcf::IndiProperty &prop, const std::string &name, const std::string &label="", const std::string &group="")
Create a standard R/W INDI switch with a single toggle element.
Definition: MagAOXApp.hpp:2321
int sendNewProperty(const pcf::IndiProperty &ipSend, const std::string &el, const T &newVal)
Send a newProperty command to another device (using the INDI Client interface)
Definition: MagAOXApp.hpp:3031
The MagAO-X ADC Tracker.
Definition: kTracker.hpp:40
pcf::IndiProperty m_indiP_tracking
Definition: kTracker.hpp:110
virtual void loadConfig()
Definition: kTracker.hpp:162
kTracker()
Default c'tor.
Definition: kTracker.hpp:128
pcf::IndiProperty m_indiP_teldata
Definition: kTracker.hpp:112
~kTracker() noexcept
D'tor, declared and defined for noexcept.
Definition: kTracker.hpp:72
float m_zero
The starting point for the K-mirorr at zd=0.
Definition: kTracker.hpp:52
virtual int appShutdown()
Shutdown the app.
Definition: kTracker.hpp:210
pcf::IndiProperty m_indiP_kpos
Definition: kTracker.hpp:115
virtual void setupConfig()
Definition: kTracker.hpp:134
INDI_SETCALLBACK_DECL(kTracker, m_indiP_teldata)
INDI_NEWCALLBACK_DECL(kTracker, m_indiP_tracking)
int loadConfigImpl(mx::app::appConfigurator &_config)
Implementation of loadConfig logic, separated for testing.
Definition: kTracker.hpp:149
friend class kTracker_test
Definition: kTracker.hpp:43
virtual int appStartup()
Startup function.
Definition: kTracker.hpp:167
int m_sign
The sign to apply to the zd to rotate the k-mirror.
Definition: kTracker.hpp:54
std::string m_tcsDevName
The device name of the TCS Interface providing 'teldata.zd'. Default is 'tcsi'.
Definition: kTracker.hpp:57
std::string m_devName
The device name of the K-mirror stage. Default is 'stagek'.
Definition: kTracker.hpp:56
bool m_tracking
The interval at which to update positions, in seconds. Default is 10 secs.
Definition: kTracker.hpp:63
virtual int appLogic()
Implementation of the FSM for kTracker.
Definition: kTracker.hpp:187
#define INDI_NEWCALLBACK(prop)
Get the name of the static callback wrapper for a new property.
Definition: indiMacros.hpp:207
#define REG_INDI_SETPROP(prop, devName, propName)
Register a SET INDI property with the class, using the standard callback name.
Definition: indiMacros.hpp:264
@ READY
The device is ready for operation, but is not operating.
Definition: stateCodes.hpp:51
#define INDI_IDLE
Definition: indiUtils.hpp:28
std::ostream & cerr()
void updateSwitchIfChanged(pcf::IndiProperty &p, const std::string &el, const pcf::IndiElement::SwitchStateType &newVal, indiDriverT *indiDriver, pcf::IndiProperty::PropertyStateType newState=pcf::IndiProperty::Ok)
Update the value of the INDI element, but only if it has changed.
Definition: indiUtils.hpp:206
const pcf::IndiProperty & ipRecv
INDI_NEWCALLBACK_DEFN(acesxeCtrl, m_indiP_windspeed)(const pcf
Definition: acesxeCtrl.hpp:687
INDI_SETCALLBACK_DEFN(MagAOXApp< _useINDI >, m_indiP_powerChannel)(const pcf
Definition: MagAOXApp.hpp:3195
Definition: dm.hpp:24