API
stdCamera.hpp
Go to the documentation of this file.
1 /** \file stdCamera.hpp
2  * \brief Standard camera interface
3  *
4  * \author Jared R. Males (jaredmales@gmail.com)
5  *
6  * \ingroup app_files
7  */
8 
9 #ifndef stdCamera_hpp
10 #define stdCamera_hpp
11 
12 #include <string>
13 #include <unordered_map>
14 
15 #include <mx/app/application.hpp>
16 
17 #include "../MagAOXApp.hpp"
18 
19 namespace MagAOX
20 {
21 namespace app
22 {
23 namespace dev
24 {
25 
26 #define CAMCTRL_E_NOCONFIGS (-10)
27 
28 /// A camera configuration
29 /** a.k.a. a mode
30  */
31 struct cameraConfig
32 {
33  std::string m_configFile; ///< The file to use for this mode, e.g. an EDT configuration file.
34  std::string m_serialCommand; ///< The command to send to the camera to place it in this mode.
35  unsigned m_centerX {0};
36  unsigned m_centerY {0};
37  unsigned m_sizeX {0};
38  unsigned m_sizeY {0};
39  unsigned m_binningX {0};
40  unsigned m_binningY {0};
41 
42  unsigned m_digitalBinX {0};
43  unsigned m_digitalBinY {0};
44 
45  float m_maxFPS {0};
46 };
47 
48 typedef std::unordered_map<std::string, cameraConfig> cameraConfigMap;
49 
50 ///Load the camera configurations contained in the app configuration into a map
51 int loadCameraConfig( cameraConfigMap & ccmap, ///< [out] the map in which to place the configurations found in config
52  mx::app::appConfigurator & config ///< [in] the application configuration structure
53  );
54 
55 /// MagAO-X standard camera interface
56 /** Implements the standard interface to a MagAO-X camera
57  *
58  *
59  * The derived class `derivedT` must be a MagAOXApp<true>, and should declare this class a friend like so:
60  * \code
61  * friend class dev::stdCamera<derivedT>;
62  * \endcode
63  *
64  * int powerOnDefaults()
65  *
66  * Temperature:
67  *
68  * A static configuration variable must be defined in derivedT as
69  * \code
70  * static constexpr bool c_stdCamera_tempControl = true; //or: false
71  * \endcode
72  * which determines whether or not temperature controls are exposed. If this is true then the derived class must implement
73  * \code
74  * int setTempControl(); // set temp control status according to m_tempControlStatusSet
75  * int setTempSetPt(); // set the temperature set point accordin gto m_ccdTempSetpt
76  * \endcode
77  *
78  * A static configuration variable must be defined in derivedT as
79  * \code
80  * static constexpr bool c_stdCamera_temp = true; //or: false
81  * \endcode
82  * which determines whether or not temperature reporting is exposed. Note that if c_stdCamera_tempControl == true, this setting does not matter,
83  * but the constexpr must still be defined. If true the INDI property temp_ccd will be updated from the value of m_ccdTemp.
84  *
85  * Readout Speed:
86  * A static configuration variable must be defined in derivedT as
87  * \code
88  * static constexpr bool c_stdCamera_readoutSpeed = true; //or: false
89  * \endcode
90  * which determines whether or not readout speed controls are exposed. If true, then the implementation should populate
91  * m_readoutSpeedNames and m_readoutSpeedNameLabels (vectors of strings) on construction to the allowed values. This
92  * facility is normally used to control both amplifier and readout/adc speed with names like "ccd_1MHz" and "emccd_17MHz".
93  * If used (and true) the
94  * \code
95  * int setReadoutSpeed();
96  * \endcode
97  * function must be define which sets the camera according to m_readoutSpeedNameSet.
98  * The implementation must also manage m_readoutSpeedName, keeping it up to date. The configuration setting camera.defaultReadoutSpeed
99  * is also exposed, and the implementation can set this default with m_defaultReadoutSpeed.
100  *
101  * Vertical Shift Speed:
102  * A static configuration variable must be defined in derivedT as
103  * \code
104  * static constexpr bool c_stdCamera_vShiftSpeed = true; //or: false
105  * \endcode
106  * which determines whether or not vertical shift speed controls are exposed. If true, then the implementation should populate
107  * m_vShiftSpeedNames and m_vShiftSpeedLabels (vectors of strings) on construction to the allowed values. This
108  * facility is normally used names like "0_3us" and "1_3us".
109  * If used (and true) the
110  * \code
111  * int setVShiftSpeed();
112  * \endcode
113  * function must be defined which sets the camera according to m_vShiftSpeedNameSet.
114  * The implementation must also manage m_vShiftSpeedName, keeping it up to date. The configuration setting camera.defaultVShiftSpeed
115  * is also exposed, and the implementation can set this default with m_defaultVShiftSpeed.
116  *
117  * Exposure Time:
118  * A static configuration variable must be defined in derivedT as
119  * \code
120  * static constexpr bool c_stdCamera_exptimeCtrl = true; //or: false
121  * \endcode
122  * \code
123  * int setExpTime();
124  * \endcode
125  *
126  * FPS Control:
127  * A static configuration variable must be defined in derivedT as
128  * \code
129  * static constexpr bool c_stdCamera_fpsCtrl = true; //or: false
130  * \endcode
131  * If that is set to true the derivedT must implement
132  * \code
133  * int setFPS();
134  * \endcode
135  *
136  * FPS Status:
137  * A static configuration variable must be defined in derivedT as
138  * \code
139  * static constexpr bool c_stdCamera_fps = true; //or: false
140  * \endcode
141  * Note that the value of c_stdCamera_fps does not matter if c_stdCamera_fpsCtrl == true.
142  *
143  * Synchro Control:
144  * A static configuration variable must be defined in derivedT as
145  * \code
146  * static constexpr bool c_stdCamera_synchro = true; //or: false
147  * \endcode
148  * If that is set to true the derivedT must implement
149  * \code
150  * int setSynchro();
151  * \endcode
152  *
153  * EM Gain:
154  * A static configuration variable must be defined in derivedT as
155  * \code
156  * static constexpr bool c_stdCamera_emGain = true; //or: false
157  * \endcode
158  * which determines whether or not EM gain controls are exposed. If the camera uses EM Gain, then
159  * a function
160  * \code
161  * int setEMGain();
162  * \endcode
163  * must be defined which sets the camera EM Gain to \ref m_emGainSet. The implementation
164  * must also keep m_emGain up to date. The value of \ref m_maxEMGain should be set by the implementation and managed
165  * as needed.
166  *
167  * Camera Modes:
168  * A static configuration variable must be defined in derivedT as
169  * \code
170  * static constexpr bool c_stdCamera_usesModes= true; //or: false
171  * \endcode
172  *
173  * Regions of Interest
174  * A static configuration variable must be defined in derivedT as
175  * \code
176  * static constexpr bool c_stdCamera_usesROI = true; //or: false
177  * \endcode
178  * The default values of m_currentROI should be set before calling stdCamera::appStartup().
179  * The derived class must implement:
180  * \code
181  * int checkNextROI(); // verifies m_nextROI values and modifies to closest valid values if needed
182  * int setNextROI(); // sets the ROI to the new target values.
183  * \endcode
184  *
185  * Crop Mode ROIs:
186  * A static configuration variable must be defined in derivedT as
187  * \code
188  * static constexpr bool c_stdCamera_cropMode = true; //or: false
189  * \endcode
190  * and the derived class must implement
191  * \code
192  * int setCropMode();
193  * \endcode
194  * which changes the crop mode according to \ref m_cropModeSet.
195  *
196  * Shutters:
197  * A static configuration variable must be defined in derivedT as
198  * \code
199  * static constexpr bool c_stdCamera_hasShutter = true; //or: false
200  * \endcode
201  * and a funciton must defined
202  * \code
203  * int setShutter(int);
204  * \endcode
205  * which shuts the shutter if the argument is 0, opens it otherwise.
206  *
207  * State:
208  * A static configuration variable must be defined in derivedT as
209  * \code
210  * static constexpr bool c_stdCamera_usesStateString = true; //or: false
211  * \endcode
212  * which determines whether the class provides a state string for dark management.
213  * If true, the following functions must be defined in derivedT:
214  * \code
215  * std::string stateString(); //String capturing the current state. Must not include "__T".
216  * bool stateStringValid(); //Whether or not the current state string is valid, i.e. not changing.
217  * \endcode
218  *
219  *
220  * The derived class must implement:
221  * \code
222  * int powerOnDefaults(); // called on power-on after powerOnWaitElapsed has occurred.
223  * \endcode
224  *
225  * Calls to this class's `setupConfig`, `loadConfig`, `appStartup`, `appLogic`, `appShutdown`
226  * `onPowerOff`, and `whilePowerOff`, must be placed in the derived class's functions of the same name.
227  *
228  * \ingroup appdev
229  */
230 template<class derivedT>
232 {
233 protected:
234 
235  /** \name Configurable Parameters
236  * @{
237  */
238 
239  cameraConfigMap m_cameraModes; ///< Map holding the possible camera mode configurations
240 
241  std::string m_startupMode; ///< The camera mode to load during first init after a power-on.
242 
243  float m_startupTemp {-999}; ///< The temperature to set after a power-on. Set to <= -999 to not use [default].
244 
245  std::string m_defaultReadoutSpeed; ///< The default readout speed of the camera.
246  std::string m_defaultVShiftSpeed; ///< The default readout speed of the camera.
247 
248  ///@}
249 
250  /** \name Temperature Control Interface
251  * @{
252  */
253 
254  float m_minTemp {-60};
255  float m_maxTemp {30};
256  float m_stepTemp {0};
257 
258  float m_ccdTemp {-999}; ///< The current temperature, in C
259 
260  float m_ccdTempSetpt {-999}; ///< The desired temperature, in C
261 
262  bool m_tempControlStatus {false}; ///< Whether or not temperature control is active
263  bool m_tempControlStatusSet {false}; ///< Desired state of temperature control
264 
265  bool m_tempControlOnTarget {false}; ///< Whether or not the temperature control system is on its target temperature
266 
267  std::string m_tempControlStatusStr; ///< Camera specific description of temperature control status.
268 
269  pcf::IndiProperty m_indiP_temp;
270  pcf::IndiProperty m_indiP_tempcont;
271  pcf::IndiProperty m_indiP_tempstat;
272 
273  ///@}
274 
275  /** \name Readout Control
276  * @{
277  */
278 
279  std::vector<std::string> m_readoutSpeedNames;
280  std::vector<std::string> m_readoutSpeedNameLabels;
281 
282  std::string m_readoutSpeedName; ///< The current readout speed name
283  std::string m_readoutSpeedNameSet; ///< The user requested readout speed name, to be set by derived()
284 
285  std::vector<std::string> m_vShiftSpeedNames;
286  std::vector<std::string> m_vShiftSpeedNameLabels;
287 
288  std::string m_vShiftSpeedName; ///< The current vshift speed name
289  std::string m_vShiftSpeedNameSet; ///< The user requested vshift speed name, to be set by derived()
290 
291  float m_adcSpeed {0};
292  float m_vshiftSpeed {0};
293 
294  float m_emGain {1}; ///< The camera's current EM gain (if available).
295  float m_emGainSet {1}; ///< The camera's EM gain, as set by the user.
296  float m_maxEMGain {1}; ///< The configurable maximum EM gain. To be enforced in derivedT.
297 
298  pcf::IndiProperty m_indiP_readoutSpeed;
299  pcf::IndiProperty m_indiP_vShiftSpeed;
300 
301  pcf::IndiProperty m_indiP_emGain;
302 
303  ///@}
304 
305  /** \name Exposure Control
306  * @{
307  */
308  float m_minExpTime {0}; ///< The minimum exposure time, used for INDI attributes
309  float m_maxExpTime {std::numeric_limits<float>::max()}; ///< The maximum exposure time, used for INDI attributes
310  float m_stepExpTime {0}; ///< The maximum exposure time stepsize, used for INDI attributes
311 
312  float m_expTime {0}; ///< The current exposure time, in seconds.
313  float m_expTimeSet {0}; ///< The exposure time, in seconds, as set by user.
314 
315  float m_minFPS{0}; ///< The minimum FPS, used for INDI attributes
316  float m_maxFPS{std::numeric_limits<float>::max()}; ///< The maximum FPS, used for INDI attributes
317  float m_stepFPS{0}; ///< The FPS step size, used for INDI attributes
318 
319  float m_fps {0}; ///< The current FPS.
320  float m_fpsSet {0}; ///< The commanded fps, as set by user.
321 
322  pcf::IndiProperty m_indiP_exptime;
323 
324  pcf::IndiProperty m_indiP_fps;
325 
326  ///@}
327 
328  /** \name External Synchronization
329  * @{
330  */
331  bool m_synchroSet {false}; ///< Target status of m_synchro
332 
333  bool m_synchro {false}; ///< Status of synchronization, true is on, false is off.
334 
335  pcf::IndiProperty m_indiP_synchro;
336 
337  ///@}
338 
339  /** \name Modes
340  *
341  * @{
342  */
343  std::string m_modeName; ///< The current mode name
344 
345  std::string m_nextMode; ///< The mode to be set by the next reconfiguration
346 
347  pcf::IndiProperty m_indiP_mode; ///< Property used to report the current mode
348 
349  pcf::IndiProperty m_indiP_reconfig; ///< Request switch which forces the framegrabber to go through the reconfigure process.
350 
351  ///@}
352 
353  /** \name ROIs
354  * ROI controls are exposed if derivedT::c_stdCamera_usesROI==true
355  * @{
356  */
357  struct roi
358  {
359  float x {0};
360  float y {0};
361  int w {0};
362  int h {0};
363  int bin_x {0};
364  int bin_y {0};
365  };
366 
370 
371  float m_minROIx {0};
372  float m_maxROIx {1023};
373  float m_stepROIx {0};
374 
375  float m_minROIy {0};
376  float m_maxROIy {1023};
377  float m_stepROIy {0};
378 
379  int m_minROIWidth {1};
380  int m_maxROIWidth {1024};
381  int m_stepROIWidth {1};
382 
383  int m_minROIHeight {1};
384  int m_maxROIHeight {1024};
386 
390 
394 
395  float m_default_x {0}; ///< Power-on ROI center x coordinate.
396  float m_default_y {0}; ///< Power-on ROI center y coordinate.
397  int m_default_w {0}; ///< Power-on ROI width.
398  int m_default_h {0}; ///< Power-on ROI height.
399  int m_default_bin_x {1}; ///< Power-on ROI x binning.
400  int m_default_bin_y {1}; ///< Power-on ROI y binning.
401 
402  float m_full_x{0}; ///< The full ROI center x coordinate.
403  float m_full_y{0}; ///< The full ROI center y coordinate.
404  int m_full_w{0}; ///< The full ROI width.
405  int m_full_h{0}; ///< The full ROI height.
406  int m_full_bin_x{1}; ///< The x-binning in the full ROI.
407  int m_full_bin_y{1}; ///< The y-binning in the full ROI.
408 
409  float m_full_currbin_x{0}; ///< The current-binning full ROI center x coordinate.
410  float m_full_currbin_y{0}; ///< The current-binning full ROI center y coordinate.
411  int m_full_currbin_w{0}; ///< The current-binning full ROI width.
412  int m_full_currbin_h{0}; ///< The current-binning full ROI height.
413 
414  pcf::IndiProperty m_indiP_roi_x; ///< Property used to set the ROI x center coordinate
415  pcf::IndiProperty m_indiP_roi_y; ///< Property used to set the ROI x center coordinate
416  pcf::IndiProperty m_indiP_roi_w; ///< Property used to set the ROI width
417  pcf::IndiProperty m_indiP_roi_h; ///< Property used to set the ROI height
418  pcf::IndiProperty m_indiP_roi_bin_x; ///< Property used to set the ROI x binning
419  pcf::IndiProperty m_indiP_roi_bin_y; ///< Property used to set the ROI y binning
420 
421  pcf::IndiProperty m_indiP_fullROI; ///< Property used to preset the full ROI dimensions.
422 
423  pcf::IndiProperty m_indiP_roi_check; ///< Property used to trigger checking the target ROI
424 
425  pcf::IndiProperty m_indiP_roi_set; ///< Property used to trigger setting the ROI
426 
427  pcf::IndiProperty m_indiP_roi_full; ///< Property used to trigger setting the full ROI.
428  pcf::IndiProperty m_indiP_roi_fullbin; ///< Property used to trigger setting the full in current binning ROI.
429  pcf::IndiProperty m_indiP_roi_loadlast; ///< Property used to trigger loading the last ROI as the target.
430  pcf::IndiProperty m_indiP_roi_last; ///< Property used to trigger setting the last ROI.
431  pcf::IndiProperty m_indiP_roi_default; ///< Property used to trigger setting the default and startup ROI.
432 
433  ///@}
434 
435  /** \name Crop Mode
436  * Crop mode controls are exposed if derivedT::c_stdCamera_cropMode==true
437  * @{
438  */
439  bool m_cropMode {false}; ///< Status of crop mode ROIs, if enabled for this camera.
440  bool m_cropModeSet {false}; ///< Desired status of crop mode ROIs, if enabled for this camera.
441 
442  pcf::IndiProperty m_indiP_cropMode; ///< Property used to toggle crop mode on and off.
443  ///@}
444 
445  /** \name Shutter Control
446  * Shutter controls are exposed if derivedT::c_stdCamera_hasShutter == true.
447  * @{
448  */
449  std::string m_shutterStatus {"UNKNOWN"};
450  int m_shutterState {-1}; /// State of the shutter. 0 = shut, 1 = open, -1 = unknown.
451 
452  pcf::IndiProperty m_indiP_shutterStatus; ///< Property to report shutter status
453  pcf::IndiProperty m_indiP_shutter; ///< Property used to control the shutter, a switch.
454 
455  ///@}
456 
457  /** \name State String
458  * The State string is exposed if derivedT::c_stdCamera_usesStateString is true.
459  * @{
460  */
461  pcf::IndiProperty m_indiP_stateString;
462  ///@}
463 
464 public:
465 
466  ///Destructor, destroys the PdvDev structure
467  ~stdCamera() noexcept;
468 
469  /// Setup the configuration system
470  /**
471  * This should be called in `derivedT::setupConfig` as
472  * \code
473  stdCamera<derivedT>::setupConfig(config);
474  \endcode
475  * with appropriate error checking.
476  */
477  void setupConfig(mx::app::appConfigurator & config /**< [out] the derived classes configurator*/);
478 
479  /// load the configuration system results
480  /**
481  * This should be called in `derivedT::loadConfig` as
482  * \code
483  stdCamera<derivedT>::loadConfig(config);
484  \endcode
485  * with appropriate error checking.
486  */
487  void loadConfig(mx::app::appConfigurator & config /**< [in] the derived classes configurator*/);
488 
489 protected:
490  //workers to create indi variables if needed
491  int createReadoutSpeed(const mx::meta::trueFalseT<true> & t);
492 
493  int createReadoutSpeed(const mx::meta::trueFalseT<false> & f);
494 
495  int createVShiftSpeed(const mx::meta::trueFalseT<true> & t);
496 
497  int createVShiftSpeed(const mx::meta::trueFalseT<false> & f);
498 
499 public:
500  /// Startup function
501  /**
502  * This should be called in `derivedT::appStartup` as
503  * \code
504  stdCamera<derivedT>::appStartup();
505  \endcode
506  * with appropriate error checking.
507  *
508  * You should set the default/startup values of m_currentROI as well as the min/max/step values for the ROI parameters
509  * before calling this function.
510  *
511  * \returns 0 on success
512  * \returns -1 on error, which is logged.
513  */
514  int appStartup();
515 
516  /// Application logic
517  /** Checks the stdCamera thread
518  *
519  * This should be called from the derived's appLogic() as in
520  * \code
521  stdCamera<derivedT>::appLogic();
522  \endcode
523  * with appropriate error checking.
524  *
525  * \returns 0 on success
526  * \returns -1 on error, which is logged.
527  */
528  int appLogic();
529 
530  /// Actions on power off
531  /**
532  * This should be called from the derived's onPowerOff() as in
533  * \code
534  stdCamera<derivedT>::onPowerOff();
535  \endcode
536  * with appropriate error checking.
537  *
538  * The INDI mutex should be locked before calling.
539  *
540  * \returns 0 on success
541  * \returns -1 on error, which is logged.
542  */
543  int onPowerOff();
544 
545  /// Actions while powered off
546  /**
547  * This should be called from the derived's whilePowerOff() as in
548  * \code
549  stdCamera<derivedT>::whilePowerOff();
550  \endcode
551  * with appropriate error checking.
552  *
553  * \returns 0 on success
554  * \returns -1 on error, which is logged.
555  */
557 
558  /// Application shutdown
559  /** Shuts down the stdCamera thread
560  *
561  * \code
562  stdCamera<derivedT>::appShutdown();
563  \endcode
564  * with appropriate error checking.
565  *
566  * \returns 0 on success
567  * \returns -1 on error, which is logged.
568  */
569  int appShutdown();
570 
571 protected:
572 
573 
574  /** \name INDI
575  *
576  *@{
577  */
578 public:
579 
580  /// The static callback function to be registered for stdCamera properties
581  /** Calls newCallback_stdCamera
582  *
583  * \returns 0 on success.
584  * \returns -1 on error.
585  */
586  static int st_newCallBack_stdCamera( void * app, ///< [in] a pointer to this, will be static_cast-ed to derivedT.
587  const pcf::IndiProperty &ipRecv ///< [in] the INDI property sent with the the new property request.
588  );
589 
590  /// The callback function for stdCamera properties
591  /** Dispatches to the relevant handler
592  *
593  * \returns 0 on success.
594  * \returns -1 on error.
595  */
596  int newCallBack_stdCamera( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
597 
598  /// Interface to setTempSetPt when the derivedT has temperature control
599  /** Tag-dispatch resolution of c_stdCamera_tempControl==true will call this function.
600  * Calls derivedT::setTempSetPt.
601  */
602  int setTempSetPt( const mx::meta::trueFalseT<true> & t);
603 
604  /// Interface to setTempSetPt when the derivedT does not have temperature control
605  /** Tag-dispatch resolution of c_stdCamera_tempControl==false will call this function.
606  * Prevents requiring derivedT::setTempSetPt.
607  */
608  int setTempSetPt( const mx::meta::trueFalseT<false> & f);
609 
610  /// Callback to process a NEW CCD temp request
611  /**
612  * \returns 0 on success.
613  * \returns -1 on error.
614  */
615  int newCallBack_temp( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
616 
617  /// Interface to setTempControl when the derivedT has temperature control
618  /** Tag-dispatch resolution of c_stdCamera_tempControl==true will call this function.
619  * Calls derivedT::setTempControl.
620  */
621  int setTempControl( const mx::meta::trueFalseT<true> & t);
622 
623  /// Interface to setTempControl when the derivedT does not have temperature control
624  /** Tag-dispatch resolution of c_stdCamera_tempControl==false will call this function.
625  * Prevents requiring derivedT::setTempControl.
626  */
627  int setTempControl( const mx::meta::trueFalseT<false> & f);
628 
629  /// Callback to process a NEW CCD temp control request
630  /**
631  * \returns 0 on success.
632  * \returns -1 on error.
633  */
634  int newCallBack_temp_controller( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
635 
636  /// Interface to setReadoutSpeed when the derivedT has readout speed control
637  /** Tag-dispatch resolution of c_stdCamera_readoutSpeed==true will call this function.
638  * Calls derivedT::setReadoutSpeed.
639  */
640  int setReadoutSpeed( const mx::meta::trueFalseT<true> & t);
641 
642  /// Interface to setReadoutSpeed when the derivedT does not have readout speed control
643  /** Tag-dispatch resolution of c_stdCamera_readoutSpeed==false will call this function.
644  * Just returns 0.
645  */
646  int setReadoutSpeed( const mx::meta::trueFalseT<false> & f);
647 
648  /// Callback to process a NEW readout speed request
649  /**
650  * \returns 0 on success.
651  * \returns -1 on error.
652  */
653  int newCallBack_readoutSpeed( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
654 
655  /// Interface to setVShiftSpeed when the derivedT has vshift speed control
656  /** Tag-dispatch resolution of c_stdCamera_vShiftSpeed==true will call this function.
657  * Calls derivedT::setVShiftSpeed.
658  */
659  int setVShiftSpeed( const mx::meta::trueFalseT<true> & t);
660 
661  /// Interface to setVShiftSpeed when the derivedT does not have vshift speed control
662  /** Tag-dispatch resolution of c_stdCamera_vShiftSpeed==false will call this function.
663  * Just returns 0.
664  */
665  int setVShiftSpeed( const mx::meta::trueFalseT<false> & f);
666 
667  /// Callback to process a NEW vshift speed request
668  /**
669  * \returns 0 on success.
670  * \returns -1 on error.
671  */
672  int newCallBack_vShiftSpeed( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
673 
674  /// Interface to setEMGain when the derivedT has EM Gain
675  /** Tag-dispatch resolution of c_stdCamera_emGain==true will call this function.
676  * Calls derivedT::setEMGain.
677  */
678  int setEMGain( const mx::meta::trueFalseT<true> & t);
679 
680  /// Interface to setEMGain when the derivedT does not have EM Gain
681  /** Tag-dispatch resolution of c_stdCamera_emGain==false will call this function.
682  * This prevents requiring derivedT to have its own setEMGain().
683  */
684  int setEMGain( const mx::meta::trueFalseT<false> & f);
685 
686  /// Callback to process a NEW EM gain request
687  /**
688  * \returns 0 on success.
689  * \returns -1 on error.
690  */
691  int newCallBack_emgain( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
692 
693  /// Interface to setExpTime when the derivedT uses exposure time controls
694  /** Tag-dispatch resolution of c_stdCamera_exptimeCtrl==true will call this function.
695  * Calls derivedT::setExpTime.
696  */
697  int setExpTime( const mx::meta::trueFalseT<true> & t );
698 
699  /// Interface to setExptime when the derivedT does not use exposure time controls.
700  /** Tag-dispatch resolution of c_stdCamera_exptimeCtrl==false will call this function.
701  * This prevents requiring derivedT to have its own setExpTime().
702  */
703  int setExpTime( const mx::meta::trueFalseT<false> & f );
704 
705  /// Callback to process a NEW exposure time request
706  /**
707  * \returns 0 on success.
708  * \returns -1 on error.
709  */
710  int newCallBack_exptime( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
711 
712  /// Interface to setFPS when the derivedT uses FPS controls
713  /** Tag-dispatch resolution of c_stdCamera_fpsCtrl==true will call this function.
714  * Calls derivedT::setFPS.
715  */
716  int setFPS( const mx::meta::trueFalseT<true> & t );
717 
718  /// Interface to setFPS when the derivedT does not use FPS controls.
719  /** Tag-dispatch resolution of c_stdCamera_hasFPS==false will call this function.
720  * This prevents requiring derivedT to have its own setFPS().
721  */
722  int setFPS( const mx::meta::trueFalseT<false> & f );
723 
724  /// Callback to process a NEW fps request
725  /**
726  * \returns 0 on success.
727  * \returns -1 on error.
728  */
729  int newCallBack_fps( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
730 
731  /// Interface to setSynchro when the derivedT has synchronization
732  /** Tag-dispatch resolution of c_stdCamera_synchro==true will call this function.
733  * Calls derivedT::setSynchro.
734  */
735  int setSynchro( const mx::meta::trueFalseT<true> & t );
736 
737  /// Interface to setSynchro when the derivedT does not have synchronization
738  /** Tag-dispatch resolution of c_stdCamera_ynchro==false will call this function.
739  * This prevents requiring derivedT to have its own setSynchro().
740  */
741  int setSynchro( const mx::meta::trueFalseT<false> & f );
742 
743  /// Callback to process a NEW synchro request
744  /**
745  * \returns 0 on success.
746  * \returns -1 on error.
747  */
748  int newCallBack_synchro( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
749 
750  /// Callback to process a NEW mode request
751  /**
752  * \returns 0 on success.
753  * \returns -1 on error.
754  */
755  int newCallBack_mode( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
756 
757  /// Callback to process a NEW reconfigure request
758  /**
759  * \returns 0 on success.
760  * \returns -1 on error.
761  */
762  int newCallBack_reconfigure( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
763 
764  /// Interface to setCropMode when the derivedT has crop mode
765  /** Tag-dispatch resolution of c_stdCamera_cropMode==true will call this function.
766  * Calls derivedT::setCropMode.
767  */
768  int setCropMode( const mx::meta::trueFalseT<true> & t);
769 
770  /// Interface to setCropMode when the derivedT does not have crop mode
771  /** Tag-dispatch resolution of c_stdCamera_cropMode==false will call this function.
772  * This prevents requiring derivedT to have its own setCropMode().
773  */
774  int setCropMode( const mx::meta::trueFalseT<false> & f);
775 
776  /// Callback to process a NEW cropMode request
777  /**
778  * \returns 0 on success.
779  * \returns -1 on error.
780  */
781  int newCallBack_cropMode( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
782 
783  /// Callback to process a NEW roi_x request
784  /**
785  * \returns 0 on success.
786  * \returns -1 on error.
787  */
788  int newCallBack_roi_x( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
789 
790  /// Callback to process a NEW roi_y request
791  /**
792  * \returns 0 on success.
793  * \returns -1 on error.
794  */
795  int newCallBack_roi_y( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
796 
797  /// Callback to process a NEW roi_w request
798  /**
799  * \returns 0 on success.
800  * \returns -1 on error.
801  */
802  int newCallBack_roi_w( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
803 
804  /// Callback to process a NEW roi_h request
805  /**
806  * \returns 0 on success.
807  * \returns -1 on error.
808  */
809  int newCallBack_roi_h( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
810 
811  /// Callback to process a NEW bin_x request
812  /**
813  * \returns 0 on success.
814  * \returns -1 on error.
815  */
816  int newCallBack_roi_bin_x( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
817 
818  /// Callback to process a NEW bin_y request
819  /**
820  * \returns 0 on success.
821  * \returns -1 on error.
822  */
823  int newCallBack_roi_bin_y( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
824 
825  /// Interface to checkNextROI when the derivedT uses ROIs
826  /** Tag-dispatch resolution of c_stdCamera_usesROI==true will call this function.
827  * Calls derivedT::checkNextROI.
828  */
829  int checkNextROI( const mx::meta::trueFalseT<true> & t);
830 
831  /// Interface to checkNextROI when the derivedT does not use ROIs.
832  /** Tag-dispatch resolution of c_stdCamera_usesROI==false will call this function.
833  * This prevents requiring derivedT to have its own checkNextROI().
834  */
835  int checkNextROI( const mx::meta::trueFalseT<false> & f);
836 
837  /// Callback to process a NEW roi_check request
838  /**
839  * \returns 0 on success.
840  * \returns -1 on error.
841  */
842  int newCallBack_roi_check( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
843 
844  /// Interface to setNextROI when the derivedT uses ROIs
845  /** Tag-dispatch resolution of c_stdCamera_usesROI==true will call this function.
846  * Calls derivedT::setNextROI.
847  */
848  int setNextROI( const mx::meta::trueFalseT<true> & t);
849 
850  /// Interface to setNextROI when the derivedT does not use ROIs.
851  /** Tag-dispatch resolution of c_stdCamera_usesROI==false will call this function.
852  * This prevents requiring derivedT to have its own setNextROI().
853  */
854  int setNextROI( const mx::meta::trueFalseT<false> & f);
855 
856  /// Callback to process a NEW roi_set request
857  /**
858  * \returns 0 on success.
859  * \returns -1 on error.
860  */
861  int newCallBack_roi_set( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
862 
863  /// Callback to process a NEW roi_full request
864  /**
865  * \returns 0 on success.
866  * \returns -1 on error.
867  */
868  int newCallBack_roi_full( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
869 
870  /// Callback to process a NEW roi_fullbin request
871  /**
872  * \returns 0 on success.
873  * \returns -1 on error.
874  */
875  int newCallBack_roi_fullbin( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
876 
877  /// Callback to process a NEW roi_loadlast request
878  /**
879  * \returns 0 on success.
880  * \returns -1 on error.
881  */
882  int newCallBack_roi_loadlast( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
883 
884  /// Callback to process a NEW roi_last request
885  /**
886  * \returns 0 on success.
887  * \returns -1 on error.
888  */
889  int newCallBack_roi_last( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
890 
891  /// Callback to process a NEW roi_default request
892  /**
893  * \returns 0 on success.
894  * \returns -1 on error.
895  */
896  int newCallBack_roi_default( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
897 
898  /// Interface to setShutter when the derivedT has a shutter
899  /** Tag-dispatch resolution of c_stdCamera_hasShutter==true will call this function.
900  * Calls derivedT::setShutter.
901  */
902  int setShutter( int ss,
903  const mx::meta::trueFalseT<true> & t
904  );
905 
906  /// Interface to setShutter when the derivedT does not have a shutter.
907  /** Tag-dispatch resolution of c_stdCamera_hasShutter==false will call this function.
908  * This prevents requiring derivedT to have its own setShutter().
909  */
910  int setShutter( int ss,
911  const mx::meta::trueFalseT<false> & f
912  );
913 
914  /// Callback to process a NEW shutter request
915  /**
916  * \returns 0 on success.
917  * \returns -1 on error.
918  */
919  int newCallBack_shutter( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
920 
921  /// Interface to stateString when the derivedT provides it
922  /** Tag-dispatch resolution of c_stdCamera_usesStateString==true will call this function.
923  * Calls derivedT::stateString.
924  */
925  std::string stateString( const mx::meta::trueFalseT<true> & t);
926 
927  /// Interface to stateString when the derivedT does not provide it
928  /** Tag-dispatch resolution of c_stdCamera_usesStateString==false will call this function.
929  * returns "".
930  */
931  std::string stateString( const mx::meta::trueFalseT<false> & f);
932 
933  /// Interface to stateStringValid when the derivedT provides it
934  /** Tag-dispatch resolution of c_stdCamera_usesStateString==true will call this function.
935  * Calls derivedT::stateStringValid.
936  */
937  bool stateStringValid( const mx::meta::trueFalseT<true> & t);
938 
939  /// Interface to stateStringValid when the derivedT does not provide it
940  /** Tag-dispatch resolution of c_stdCamera_usesStateString==false will call this function.
941  * returns false.
942  */
943  bool stateStringValid( const mx::meta::trueFalseT<false> & f);
944 
945  /// Update the INDI properties for this device controller
946  /** You should call this once per main loop.
947  * It is not called automatically.
948  *
949  * \returns 0 on success.
950  * \returns -1 on error.
951  */
952  int updateINDI();
953 
954  ///@}
955 
956  /** \name Telemeter Interface
957  * @{
958  */
959 
960  int recordCamera( bool force = false );
961 
962  ///@}
963 
964 private:
965  derivedT & derived()
966  {
967  return *static_cast<derivedT *>(this);
968  }
969 };
970 
971 template<class derivedT>
973 {
974  return;
975 }
976 
977 
978 
979 template<class derivedT>
980 void stdCamera<derivedT>::setupConfig(mx::app::appConfigurator & config)
981 {
982  if(derivedT::c_stdCamera_tempControl)
983  {
984  config.add("camera.startupTemp", "", "camera.startupTemp", argType::Required, "camera", "startupTemp", false, "float", "The temperature setpoint to set after a power-on [C]. Default is 20 C.");
985  }
986 
987  if(derivedT::c_stdCamera_readoutSpeed)
988  {
989  config.add("camera.defaultReadoutSpeed", "", "camera.defaultReadoutSpeed", argType::Required, "camera", "defaultReadoutSpeed", false, "string", "The default amplifier and readout speed.");
990  }
991 
992  if(derivedT::c_stdCamera_vShiftSpeed)
993  {
994  config.add("camera.defaultVShiftSpeed", "", "camera.defaultVShiftSpeed", argType::Required, "camera", "defaultVShiftSpeed", false, "string", "The default vertical shift speed.");
995  }
996 
997  if(derivedT::c_stdCamera_emGain)
998  {
999  config.add("camera.maxEMGain", "", "camera.maxEMGain", argType::Required, "camera", "maxEMGain", false, "unsigned", "The maximum EM gain which can be set by the user.");
1000  }
1001 
1002  if(derivedT::c_stdCamera_usesModes)
1003  {
1004  config.add("camera.startupMode", "", "camera.startupMode", argType::Required, "camera", "startupMode", false, "string", "The mode to set upon power on or application startup.");
1005  }
1006 
1007  if(derivedT::c_stdCamera_usesROI)
1008  {
1009  config.add("camera.default_x", "", "camera.default_x", argType::Required, "camera", "default_x", false, "float", "The default ROI x position.");
1010  config.add("camera.default_y", "", "camera.default_y", argType::Required, "camera", "default_y", false, "float", "The default ROI y position.");
1011  config.add("camera.default_w", "", "camera.default_w", argType::Required, "camera", "default_w", false, "int", "The default ROI width.");
1012  config.add("camera.default_h", "", "camera.default_h", argType::Required, "camera", "default_h", false, "int", "The default ROI height.");
1013  config.add("camera.default_bin_x", "", "camera.default_bin_x", argType::Required, "camera", "default_bin_x", false, "int", "The default ROI x binning.");
1014  config.add("camera.default_bin_y", "", "camera.default_bin_y", argType::Required, "camera", "default_bin_y", false, "int", "The default ROI y binning.");
1015  }
1016 }
1017 
1018 template<class derivedT>
1019 void stdCamera<derivedT>::loadConfig(mx::app::appConfigurator & config)
1020 {
1021  if(derivedT::c_stdCamera_tempControl)
1022  {
1023  config(m_startupTemp, "camera.startupTemp");
1024  }
1025 
1026  if(derivedT::c_stdCamera_readoutSpeed)
1027  {
1028  config(m_defaultReadoutSpeed, "camera.defaultReadoutSpeed");
1029  }
1030 
1031  if(derivedT::c_stdCamera_vShiftSpeed)
1032  {
1033  config(m_defaultVShiftSpeed, "camera.defaultVShiftSpeed");
1034  }
1035 
1036  if(derivedT::c_stdCamera_emGain)
1037  {
1038  config(m_maxEMGain, "camera.maxEMGain");
1039  }
1040 
1041  if(derivedT::c_stdCamera_usesModes)
1042  {
1043  int rv = loadCameraConfig(m_cameraModes, config);
1044 
1045  if(rv < 0)
1046  {
1047  if(rv == CAMCTRL_E_NOCONFIGS)
1048  {
1049  derivedT::template log<text_log>("No camera configurations found.", logPrio::LOG_CRITICAL);
1050  }
1051  }
1052 
1053  config(m_startupMode, "camera.startupMode");
1054 
1055  }
1056 
1057  if(derivedT::c_stdCamera_usesROI)
1058  {
1059  config(m_default_x, "camera.default_x");
1060  config(m_default_y, "camera.default_y");
1061  config(m_default_w, "camera.default_w");
1062  config(m_default_h, "camera.default_h");
1063  config(m_default_bin_x, "camera.default_bin_x");
1064  config(m_default_bin_y, "camera.default_bin_y");
1065  }
1066 }
1067 
1068 template<class derivedT>
1069 int stdCamera<derivedT>::createReadoutSpeed(const mx::meta::trueFalseT<true> & t)
1070 {
1071  static_cast<void>(t);
1072 
1073  derived().createStandardIndiSelectionSw(m_indiP_readoutSpeed, "readout_speed", m_readoutSpeedNames, "Readout Speed");
1074 
1075  //Set the labes if provided
1076  if(m_readoutSpeedNameLabels.size() == m_readoutSpeedNames.size())
1077  {
1078  for(size_t n=0; n< m_readoutSpeedNames.size(); ++n) m_indiP_readoutSpeed[m_readoutSpeedNames[n]].setLabel(m_readoutSpeedNameLabels[n]);
1079  }
1080 
1081  derived().registerIndiPropertyNew(m_indiP_readoutSpeed, st_newCallBack_stdCamera);
1082 
1083  return 0;
1084 }
1085 
1086 template<class derivedT>
1087 int stdCamera<derivedT>::createReadoutSpeed(const mx::meta::trueFalseT<0> & f)
1088 {
1089  static_cast<void>(f);
1090 
1091  return 0;
1092 }
1093 
1094 template<class derivedT>
1095 int stdCamera<derivedT>::createVShiftSpeed(const mx::meta::trueFalseT<true> & t)
1096 {
1097  static_cast<void>(t);
1098 
1099  derived().createStandardIndiSelectionSw(m_indiP_vShiftSpeed, "vshift_speed", m_vShiftSpeedNames, "Vert. Shift Speed");
1100 
1101  if(m_vShiftSpeedNameLabels.size() == m_vShiftSpeedNames.size())
1102  {
1103  for(size_t n=0; n< m_vShiftSpeedNames.size(); ++n) m_indiP_vShiftSpeed[m_vShiftSpeedNames[n]].setLabel(m_vShiftSpeedNameLabels[n]);
1104  }
1105 
1106  derived().registerIndiPropertyNew(m_indiP_vShiftSpeed, st_newCallBack_stdCamera);
1107 
1108  return 0;
1109 }
1110 
1111 template<class derivedT>
1112 int stdCamera<derivedT>::createVShiftSpeed(const mx::meta::trueFalseT<0> & f)
1113 {
1114  static_cast<void>(f);
1115 
1116  return 0;
1117 }
1118 
1119 template<class derivedT>
1121 {
1122 
1123  if(derivedT::c_stdCamera_tempControl)
1124  {
1125  //The min/max/step values should be set in derivedT before this is called.
1126  derived().createStandardIndiNumber( m_indiP_temp, "temp_ccd", m_minTemp, m_maxTemp, m_stepTemp, "%0.1f","CCD Temperature", "CCD Temperature");
1127  m_indiP_temp["current"].set(m_ccdTemp);
1128  m_indiP_temp["target"].set(m_ccdTempSetpt);
1129  if( derived().registerIndiPropertyNew( m_indiP_temp, st_newCallBack_stdCamera) < 0)
1130  {
1131  #ifndef STDCAMERA_TEST_NOLOG
1132  derivedT::template log<software_error>({__FILE__,__LINE__});
1133  #endif
1134  return -1;
1135  }
1136 
1137  derived().createStandardIndiToggleSw( m_indiP_tempcont, "temp_controller", "CCD Temperature", "Control On/Off");
1138  m_indiP_tempcont["toggle"].set(pcf::IndiElement::Off);
1139  if( derived().registerIndiPropertyNew( m_indiP_tempcont, st_newCallBack_stdCamera) < 0)
1140  {
1141  #ifndef STDCAMERA_TEST_NOLOG
1142  derivedT::template log<software_error>({__FILE__,__LINE__});
1143  #endif
1144  return -1;
1145  }
1146 
1147  derived().createROIndiText( m_indiP_tempstat, "temp_control", "status", "CCD Temperature", "", "CCD Temperature");
1148  if( derived().registerIndiPropertyReadOnly( m_indiP_tempstat ) < 0)
1149  {
1150  #ifndef STDCAMERA_TEST_NOLOG
1151  derivedT::template log<software_error>({__FILE__,__LINE__});
1152  #endif
1153  return -1;
1154  }
1155  }
1156  else if(derivedT::c_stdCamera_temp)
1157  {
1158  derived().createROIndiNumber( m_indiP_temp, "temp_ccd", "CCD Temperature", "CCD Temperature");
1159  m_indiP_temp.add(pcf::IndiElement("current"));
1160  m_indiP_temp["current"].set(m_ccdTemp);
1161  if( derived().registerIndiPropertyReadOnly( m_indiP_temp) < 0)
1162  {
1163  #ifndef STDCAMERA_TEST_NOLOG
1164  derivedT::template log<software_error>({__FILE__,__LINE__});
1165  #endif
1166  return -1;
1167  }
1168  }
1169 
1170  if(derivedT::c_stdCamera_readoutSpeed)
1171  {
1172  mx::meta::trueFalseT<derivedT::c_stdCamera_readoutSpeed> tf;
1173  if(createReadoutSpeed(tf) < 0)
1174  {
1175  #ifndef STDCAMERA_TEST_NOLOG
1176  derivedT::template log<software_error>({__FILE__,__LINE__});
1177  #endif
1178  return -1;
1179  }
1180 
1181  }
1182 
1183  if(derivedT::c_stdCamera_vShiftSpeed)
1184  {
1185  mx::meta::trueFalseT<derivedT::c_stdCamera_vShiftSpeed> tf;
1186  if(createVShiftSpeed(tf) < 0)
1187  {
1188  #ifndef STDCAMERA_TEST_NOLOG
1189  derivedT::template log<software_error>({__FILE__,__LINE__});
1190  #endif
1191  return -1;
1192  }
1193 
1194  }
1195 
1196  if(derivedT::c_stdCamera_emGain)
1197  {
1198  derived().createStandardIndiNumber( m_indiP_emGain, "emgain", 0, 1000, 1, "%0.3f");
1199  if( derived().registerIndiPropertyNew( m_indiP_emGain, st_newCallBack_stdCamera) < 0)
1200  {
1201  #ifndef STDCAMERA_TEST_NOLOG
1202  derivedT::template log<software_error>({__FILE__,__LINE__});
1203  #endif
1204  return -1;
1205  }
1206  }
1207 
1208  if(derivedT::c_stdCamera_exptimeCtrl)
1209  {
1210  derived().createStandardIndiNumber( m_indiP_exptime, "exptime", m_minExpTime, m_maxExpTime, m_stepExpTime, "%0.3f");
1211  if( derived().registerIndiPropertyNew( m_indiP_exptime, st_newCallBack_stdCamera) < 0)
1212  {
1213  #ifndef STDCAMERA_TEST_NOLOG
1214  derivedT::template log<software_error>({__FILE__,__LINE__});
1215  #endif
1216  return -1;
1217  }
1218  }
1219 
1220  if(derivedT::c_stdCamera_fpsCtrl)
1221  {
1222  derived().createStandardIndiNumber( m_indiP_fps, "fps", m_minFPS, m_maxFPS, m_stepFPS, "%0.2f");
1223  if( derived().registerIndiPropertyNew( m_indiP_fps, st_newCallBack_stdCamera) < 0)
1224  {
1225  #ifndef STDCAMERA_TEST_NOLOG
1226  derivedT::template log<software_error>({__FILE__,__LINE__});
1227  #endif
1228  return -1;
1229  }
1230  }
1231  else if(derivedT::c_stdCamera_fps)
1232  {
1233  derived().createROIndiNumber( m_indiP_fps, "fps");
1234  m_indiP_fps.add(pcf::IndiElement("current"));
1235  m_indiP_fps["current"].setMin(m_minFPS);
1236  m_indiP_fps["current"].setMax(m_maxFPS);
1237  m_indiP_fps["current"].setStep(m_stepFPS);
1238  m_indiP_fps["current"].setFormat("%0.2f");
1239 
1240  if( derived().registerIndiPropertyReadOnly( m_indiP_fps ) < 0)
1241  {
1242  #ifndef STDCAMERA_TEST_NOLOG
1243  derivedT::template log<software_error>({__FILE__,__LINE__});
1244  #endif
1245  return -1;
1246  }
1247  }
1248 
1249  if(derivedT::c_stdCamera_synchro)
1250  {
1251  derived().createStandardIndiToggleSw( m_indiP_synchro, "synchro", "Synchronization", "Synchronization");
1252  if( derived().registerIndiPropertyNew( m_indiP_synchro, st_newCallBack_stdCamera) < 0)
1253  {
1254  #ifndef STDCAMERA_TEST_NOLOG
1255  derivedT::template log<software_error>({__FILE__,__LINE__});
1256  #endif
1257  return -1;
1258  }
1259  }
1260 
1261  if(derivedT::c_stdCamera_usesModes)
1262  {
1263  std::vector<std::string> modeNames;
1264  for(auto it = m_cameraModes.begin(); it!=m_cameraModes.end(); ++it)
1265  {
1266  modeNames.push_back(it->first);
1267  }
1268 
1269  if(derived().createStandardIndiSelectionSw( m_indiP_mode, "mode", modeNames) < 0)
1270  {
1271  derivedT::template log<software_critical>({__FILE__, __LINE__});
1272  return -1;
1273  }
1274  if( derived().registerIndiPropertyNew( m_indiP_mode, st_newCallBack_stdCamera) < 0)
1275  {
1276  #ifndef STDCAMERA_TEST_NOLOG
1277  derivedT::template log<software_error>({__FILE__,__LINE__});
1278  #endif
1279  return -1;
1280  }
1281  }
1282 
1283  derived().createStandardIndiRequestSw( m_indiP_reconfig, "reconfigure");
1284  if( derived().registerIndiPropertyNew( m_indiP_reconfig, st_newCallBack_stdCamera) < 0)
1285  {
1286  #ifndef STDCAMERA_TEST_NOLOG
1287  derivedT::template log<software_error>({__FILE__,__LINE__});
1288  #endif
1289  return -1;
1290  }
1291 
1292  if(derivedT::c_stdCamera_usesROI)
1293  {
1294  //The min/max/step values should be set in derivedT before this is called.
1295  derived().createStandardIndiNumber( m_indiP_roi_x, "roi_region_x", m_minROIx, m_maxROIx, m_stepROIx, "%0.1f");
1296  if( derived().registerIndiPropertyNew( m_indiP_roi_x, st_newCallBack_stdCamera) < 0)
1297  {
1298  #ifndef STDCAMERA_TEST_NOLOG
1299  derivedT::template log<software_error>({__FILE__,__LINE__});
1300  #endif
1301  return -1;
1302  }
1303 
1304  derived().createStandardIndiNumber( m_indiP_roi_y, "roi_region_y", m_minROIy, m_maxROIy, m_stepROIy, "%0.1f");
1305  if( derived().registerIndiPropertyNew( m_indiP_roi_y, st_newCallBack_stdCamera) < 0)
1306  {
1307  #ifndef STDCAMERA_TEST_NOLOG
1308  derivedT::template log<software_error>({__FILE__,__LINE__});
1309  #endif
1310  return -1;
1311  }
1312 
1313  derived().createStandardIndiNumber( m_indiP_roi_w, "roi_region_w", m_minROIWidth, m_maxROIWidth, m_stepROIWidth, "%d");
1314  if( derived().registerIndiPropertyNew( m_indiP_roi_w, st_newCallBack_stdCamera) < 0)
1315  {
1316  #ifndef STDCAMERA_TEST_NOLOG
1317  derivedT::template log<software_error>({__FILE__,__LINE__});
1318  #endif
1319  return -1;
1320  }
1321 
1322  derived().createStandardIndiNumber( m_indiP_roi_h, "roi_region_h", m_minROIHeight, m_maxROIHeight, m_stepROIHeight, "%d");
1323  if( derived().registerIndiPropertyNew( m_indiP_roi_h, st_newCallBack_stdCamera) < 0)
1324  {
1325  #ifndef STDCAMERA_TEST_NOLOG
1326  derivedT::template log<software_error>({__FILE__,__LINE__});
1327  #endif
1328  return -1;
1329  }
1330 
1331  derived().createStandardIndiNumber( m_indiP_roi_bin_x, "roi_region_bin_x", m_minROIBinning_x, m_maxROIBinning_x, m_stepROIBinning_x, "%f");
1332  if( derived().registerIndiPropertyNew( m_indiP_roi_bin_x, st_newCallBack_stdCamera) < 0)
1333  {
1334  #ifndef STDCAMERA_TEST_NOLOG
1335  derivedT::template log<software_error>({__FILE__,__LINE__});
1336  #endif
1337  return -1;
1338  }
1339 
1340  derived().createStandardIndiNumber( m_indiP_roi_bin_y, "roi_region_bin_y", m_minROIBinning_y, m_maxROIBinning_y, m_stepROIBinning_y, "%f");
1341  if( derived().registerIndiPropertyNew( m_indiP_roi_bin_y, st_newCallBack_stdCamera) < 0)
1342  {
1343  #ifndef STDCAMERA_TEST_NOLOG
1344  derivedT::template log<software_error>({__FILE__,__LINE__});
1345  #endif
1346  return -1;
1347  }
1348 
1349  derived().createROIndiNumber( m_indiP_fullROI, "roi_full_region");
1350  m_indiP_fullROI.add(pcf::IndiElement("x"));
1351  m_indiP_fullROI["x"] = 0;
1352  m_indiP_fullROI.add(pcf::IndiElement("y"));
1353  m_indiP_fullROI["y"] = 0;
1354  m_indiP_fullROI.add(pcf::IndiElement("w"));
1355  m_indiP_fullROI["w"] = 0;
1356  m_indiP_fullROI.add(pcf::IndiElement("h"));
1357  m_indiP_fullROI["h"] = 0;
1358  if( derived().registerIndiPropertyReadOnly( m_indiP_fullROI ) < 0)
1359  {
1360  #ifndef STDCAMERA_TEST_NOLOG
1361  derivedT::template log<software_error>({__FILE__,__LINE__});
1362  #endif
1363  return -1;
1364  }
1365 
1366  derived().createStandardIndiRequestSw( m_indiP_roi_check, "roi_region_check");
1367  if( derived().registerIndiPropertyNew( m_indiP_roi_check, st_newCallBack_stdCamera) < 0)
1368  {
1369  #ifndef STDCAMERA_TEST_NOLOG
1370  derivedT::template log<software_error>({__FILE__,__LINE__});
1371  #endif
1372  return -1;
1373  }
1374 
1375  derived().createStandardIndiRequestSw( m_indiP_roi_set, "roi_set");
1376  if( derived().registerIndiPropertyNew( m_indiP_roi_set, st_newCallBack_stdCamera) < 0)
1377  {
1378  #ifndef STDCAMERA_TEST_NOLOG
1379  derivedT::template log<software_error>({__FILE__,__LINE__});
1380  #endif
1381  return -1;
1382  }
1383 
1384  derived().createStandardIndiRequestSw( m_indiP_roi_full, "roi_set_full");
1385  if( derived().registerIndiPropertyNew( m_indiP_roi_full, st_newCallBack_stdCamera) < 0)
1386  {
1387  #ifndef STDCAMERA_TEST_NOLOG
1388  derivedT::template log<software_error>({__FILE__,__LINE__});
1389  #endif
1390  return -1;
1391  }
1392 
1393  derived().createStandardIndiRequestSw( m_indiP_roi_fullbin, "roi_set_full_bin");
1394  if( derived().registerIndiPropertyNew( m_indiP_roi_fullbin, st_newCallBack_stdCamera) < 0)
1395  {
1396  #ifndef STDCAMERA_TEST_NOLOG
1397  derivedT::template log<software_error>({__FILE__,__LINE__});
1398  #endif
1399  return -1;
1400  }
1401 
1402  derived().createStandardIndiRequestSw( m_indiP_roi_loadlast, "roi_load_last");
1403  if( derived().registerIndiPropertyNew( m_indiP_roi_loadlast, st_newCallBack_stdCamera) < 0)
1404  {
1405  #ifndef STDCAMERA_TEST_NOLOG
1406  derivedT::template log<software_error>({__FILE__,__LINE__});
1407  #endif
1408  return -1;
1409  }
1410 
1411  derived().createStandardIndiRequestSw( m_indiP_roi_last, "roi_set_last");
1412  if( derived().registerIndiPropertyNew( m_indiP_roi_last, st_newCallBack_stdCamera) < 0)
1413  {
1414  #ifndef STDCAMERA_TEST_NOLOG
1415  derivedT::template log<software_error>({__FILE__,__LINE__});
1416  #endif
1417  return -1;
1418  }
1419 
1420  derived().createStandardIndiRequestSw( m_indiP_roi_default, "roi_set_default");
1421  if( derived().registerIndiPropertyNew( m_indiP_roi_default, st_newCallBack_stdCamera) < 0)
1422  {
1423  #ifndef STDCAMERA_TEST_NOLOG
1424  derivedT::template log<software_error>({__FILE__,__LINE__});
1425  #endif
1426  return -1;
1427  }
1428  }
1429 
1430  if(derivedT::c_stdCamera_cropMode)
1431  {
1432  derived().createStandardIndiToggleSw( m_indiP_cropMode, "roi_crop_mode", "Crop Mode", "Crop Mode");
1433  if( derived().registerIndiPropertyNew( m_indiP_cropMode, st_newCallBack_stdCamera) < 0)
1434  {
1435  #ifndef STDCAMERA_TEST_NOLOG
1436  derivedT::template log<software_error>({__FILE__,__LINE__});
1437  #endif
1438  return -1;
1439  }
1440  }
1441 
1442  //Set up INDI for shutter
1443  if(derivedT::c_stdCamera_hasShutter)
1444  {
1445  derived().createROIndiText( m_indiP_shutterStatus, "shutter_status", "status", "Shutter Status", "Shutter", "Status");
1446  m_indiP_shutterStatus["status"] = m_shutterStatus;
1447  if( derived().registerIndiPropertyReadOnly( m_indiP_shutterStatus ) < 0)
1448  {
1449  #ifndef STDCAMERA_TEST_NOLOG
1450  derivedT::template log<software_error>({__FILE__,__LINE__});
1451  #endif
1452  return -1;
1453  }
1454 
1455  derived().createStandardIndiToggleSw( m_indiP_shutter, "shutter", "Shutter", "Shutter");
1456  if( derived().registerIndiPropertyNew( m_indiP_shutter, st_newCallBack_stdCamera) < 0)
1457  {
1458  #ifndef STDCAMERA_TEST_NOLOG
1459  derivedT::template log<software_error>({__FILE__,__LINE__});
1460  #endif
1461  return -1;
1462  }
1463 
1464  }
1465 
1466  if(derivedT::c_stdCamera_usesStateString)
1467  {
1468  derived().createROIndiText( m_indiP_stateString, "state_string", "current", "State String", "State", "String");
1469  m_indiP_stateString.add(pcf::IndiElement("valid"));
1470  m_indiP_stateString["valid"] = "no";
1471  if( derived().registerIndiPropertyReadOnly( m_indiP_stateString ) < 0)
1472  {
1473  #ifndef STDCAMERA_TEST_NOLOG
1474  derivedT::template log<software_error>({__FILE__,__LINE__});
1475  #endif
1476  return -1;
1477  }
1478  }
1479 
1480  return 0;
1481 }//int stdCamera<derivedT>::appStartup()
1482 
1483 template<class derivedT>
1485 {
1486  if( derived().state() == stateCodes::POWERON )
1487  {
1488  if(derived().powerOnWaitElapsed())
1489  {
1490  derived().state(stateCodes::NOTCONNECTED);
1491 
1492  //Set power-on defaults
1493  derived().powerOnDefaults();
1494 
1495  if(derivedT::c_stdCamera_tempControl)
1496  {
1497  //then set startupTemp if configured
1498  if(m_startupTemp > -999) m_ccdTempSetpt = m_startupTemp;
1499  derived().updateIfChanged(m_indiP_temp, "target", m_ccdTempSetpt, INDI_IDLE);
1500  }
1501 
1502  if(derivedT::c_stdCamera_usesROI)
1503  {
1504  //m_currentROI should be set to default/startup values in derivedT::powerOnDefaults
1505  m_nextROI.x = m_currentROI.x;
1506  m_nextROI.y = m_currentROI.y;
1507  m_nextROI.w = m_currentROI.w;
1508  m_nextROI.h = m_currentROI.h;
1509  m_nextROI.bin_x = m_currentROI.bin_x;
1510  m_nextROI.bin_y = m_currentROI.bin_y;
1511 
1512  derived().updateIfChanged(m_indiP_roi_x, "current", m_currentROI.x, INDI_IDLE);
1513  derived().updateIfChanged(m_indiP_roi_x, "target", m_nextROI.x, INDI_IDLE);
1514 
1515  derived().updateIfChanged(m_indiP_roi_y, "current", m_currentROI.y, INDI_IDLE);
1516  derived().updateIfChanged(m_indiP_roi_y, "target", m_nextROI.y, INDI_IDLE);
1517 
1518  derived().updateIfChanged(m_indiP_roi_w, "current", m_currentROI.w, INDI_IDLE);
1519  derived().updateIfChanged(m_indiP_roi_w, "target", m_nextROI.w, INDI_IDLE);
1520 
1521  derived().updateIfChanged(m_indiP_roi_h, "current", m_currentROI.h, INDI_IDLE);
1522  derived().updateIfChanged(m_indiP_roi_h, "target", m_nextROI.h, INDI_IDLE);
1523 
1524  derived().updateIfChanged(m_indiP_roi_bin_x, "current", m_currentROI.bin_x, INDI_IDLE);
1525  derived().updateIfChanged(m_indiP_roi_bin_x, "target", m_nextROI.bin_x, INDI_IDLE);
1526 
1527  derived().updateIfChanged(m_indiP_roi_bin_y, "current", m_currentROI.bin_y, INDI_IDLE);
1528  derived().updateIfChanged(m_indiP_roi_bin_y, "target", m_nextROI.bin_y, INDI_IDLE);
1529  }
1530 
1531  if(derivedT::c_stdCamera_hasShutter)
1532  {
1533  if(m_shutterStatus == "OPERATING")
1534  {
1535  derived().updateIfChanged(m_indiP_shutterStatus, "status", m_shutterStatus, INDI_BUSY);
1536  }
1537  if(m_shutterStatus == "POWERON" || m_shutterStatus == "READY")
1538  {
1539  derived().updateIfChanged(m_indiP_shutterStatus, "status", m_shutterStatus, INDI_OK);
1540  }
1541  else
1542  {
1543  derived().updateIfChanged(m_indiP_shutterStatus, "status", m_shutterStatus, INDI_IDLE);
1544  }
1545 
1546  if(m_shutterState == 1)
1547  {
1548  derived().updateSwitchIfChanged(m_indiP_shutter, "toggle", pcf::IndiElement::On, INDI_OK);
1549  }
1550  else
1551  {
1552  derived().updateSwitchIfChanged(m_indiP_shutter, "toggle", pcf::IndiElement::Off, INDI_IDLE);
1553  }
1554  }
1555 
1556  return 0;
1557  }
1558  else
1559  {
1560  return 0;
1561  }
1562  }
1563  else if( derived().state() == stateCodes::READY || derived().state() == stateCodes::OPERATING )
1564  {
1565  if(derivedT::c_stdCamera_usesROI)
1566  {
1567  derived().updateIfChanged(m_indiP_roi_x, "current", m_currentROI.x, INDI_IDLE);
1568  derived().updateIfChanged(m_indiP_roi_x, "target", m_nextROI.x, INDI_IDLE);
1569 
1570  derived().updateIfChanged(m_indiP_roi_y, "current", m_currentROI.y, INDI_IDLE);
1571  derived().updateIfChanged(m_indiP_roi_y, "target", m_nextROI.y, INDI_IDLE);
1572 
1573  derived().updateIfChanged(m_indiP_roi_w, "current", m_currentROI.w, INDI_IDLE);
1574  derived().updateIfChanged(m_indiP_roi_w, "target", m_nextROI.w, INDI_IDLE);
1575 
1576  derived().updateIfChanged(m_indiP_roi_h, "current", m_currentROI.h, INDI_IDLE);
1577  derived().updateIfChanged(m_indiP_roi_h, "target", m_nextROI.h, INDI_IDLE);
1578 
1579  derived().updateIfChanged(m_indiP_roi_bin_x, "current", m_currentROI.bin_x, INDI_IDLE);
1580  derived().updateIfChanged(m_indiP_roi_bin_x, "target", m_nextROI.bin_x, INDI_IDLE);
1581 
1582  derived().updateIfChanged(m_indiP_roi_bin_y, "current", m_currentROI.bin_y, INDI_IDLE);
1583  derived().updateIfChanged(m_indiP_roi_bin_y, "target", m_nextROI.bin_y, INDI_IDLE);
1584  }
1585  }
1586 
1587  return 0;
1588 
1589 }
1590 
1591 template<class derivedT>
1593 {
1594  if( !derived().m_indiDriver ) return 0;
1595 
1596  if(derivedT::c_stdCamera_usesModes)
1597  {
1598  for(auto it = m_cameraModes.begin();it!=m_cameraModes.end();++it)
1599  {
1600  derived().updateSwitchIfChanged(m_indiP_mode, it->first, pcf::IndiElement::Off, INDI_IDLE);
1601  }
1602  }
1603 
1604  if(derivedT::c_stdCamera_usesROI)
1605  {
1606  indi::updateIfChanged(m_indiP_roi_x, "current", std::string(""), derived().m_indiDriver, INDI_IDLE);
1607  indi::updateIfChanged(m_indiP_roi_x, "target", std::string(""), derived().m_indiDriver, INDI_IDLE);
1608 
1609  indi::updateIfChanged(m_indiP_roi_y, "current", std::string(""), derived().m_indiDriver, INDI_IDLE);
1610  indi::updateIfChanged(m_indiP_roi_y, "target", std::string(""), derived().m_indiDriver, INDI_IDLE);
1611 
1612  indi::updateIfChanged(m_indiP_roi_w, "current", std::string(""), derived().m_indiDriver, INDI_IDLE);
1613  indi::updateIfChanged(m_indiP_roi_w, "target", std::string(""), derived().m_indiDriver, INDI_IDLE);
1614 
1615  indi::updateIfChanged(m_indiP_roi_h, "current", std::string(""), derived().m_indiDriver, INDI_IDLE);
1616  indi::updateIfChanged(m_indiP_roi_h, "target", std::string(""), derived().m_indiDriver, INDI_IDLE);
1617 
1618  indi::updateIfChanged(m_indiP_roi_bin_x, "current", std::string(""), derived().m_indiDriver, INDI_IDLE);
1619  indi::updateIfChanged(m_indiP_roi_bin_x, "target", std::string(""), derived().m_indiDriver, INDI_IDLE);
1620 
1621  indi::updateIfChanged(m_indiP_roi_bin_y, "current", std::string(""), derived().m_indiDriver, INDI_IDLE);
1622  indi::updateIfChanged(m_indiP_roi_bin_y, "target", std::string(""), derived().m_indiDriver, INDI_IDLE);
1623  }
1624 
1625  //Shutters can be independent pieces of hardware . . .
1626  if(derivedT::c_stdCamera_hasShutter)
1627  {
1628  if(m_shutterStatus == "OPERATING")
1629  {
1630  derived().updateIfChanged(m_indiP_shutterStatus, "status", m_shutterStatus, INDI_BUSY);
1631  }
1632  if(m_shutterStatus == "POWERON" || m_shutterStatus == "READY")
1633  {
1634  derived().updateIfChanged(m_indiP_shutterStatus, "status", m_shutterStatus, INDI_OK);
1635  }
1636  else
1637  {
1638  derived().updateIfChanged(m_indiP_shutterStatus, "status", m_shutterStatus, INDI_IDLE);
1639  }
1640 
1641  if(m_shutterState == 0)
1642  {
1643  derived().updateSwitchIfChanged(m_indiP_shutter, "toggle", pcf::IndiElement::On, INDI_OK);
1644  }
1645  else
1646  {
1647  derived().updateSwitchIfChanged(m_indiP_shutter, "toggle", pcf::IndiElement::Off, INDI_IDLE);
1648  }
1649  }
1650 
1651  return 0;
1652 }
1653 
1654 template<class derivedT>
1656 {
1657  //Shutters can be independent pieces of hardware . . .
1658  if(derivedT::c_stdCamera_hasShutter)
1659  {
1660  if(m_shutterStatus == "OPERATING")
1661  {
1662  derived().updateIfChanged(m_indiP_shutterStatus, "status", m_shutterStatus, INDI_BUSY);
1663  }
1664  if(m_shutterStatus == "POWERON" || m_shutterStatus == "READY")
1665  {
1666  derived().updateIfChanged(m_indiP_shutterStatus, "status", m_shutterStatus, INDI_OK);
1667  }
1668  else
1669  {
1670  derived().updateIfChanged(m_indiP_shutterStatus, "status", m_shutterStatus, INDI_IDLE);
1671  }
1672 
1673  if(m_shutterState == 0)
1674  {
1675  derived().updateSwitchIfChanged(m_indiP_shutter, "toggle", pcf::IndiElement::On, INDI_OK);
1676  }
1677  else
1678  {
1679  derived().updateSwitchIfChanged(m_indiP_shutter, "toggle", pcf::IndiElement::Off, INDI_IDLE);
1680  }
1681  }
1682 
1683  return 0;
1684 }
1685 
1686 template<class derivedT>
1688 {
1689  return 0;
1690 }
1691 
1692 
1693 template<class derivedT>
1695  const pcf::IndiProperty &ipRecv
1696  )
1697 {
1698  derivedT * _app = static_cast<derivedT *>(app);
1699  return _app->newCallBack_stdCamera(ipRecv);
1700 }
1701 
1702 template<class derivedT>
1704 {
1705 
1706  if(ipRecv.getDevice() != derived().configName())
1707  {
1708  #ifndef XWCTEST_INDI_CALLBACK_VALIDATION
1709  derivedT::template log<software_error>({__FILE__, __LINE__, "unknown INDI property"});
1710  #endif
1711 
1712  return -1;
1713  }
1714 
1715  std::string name = ipRecv.getName();
1716 
1717  if( name == "reconfigure") return newCallBack_reconfigure(ipRecv);
1718  else if(derivedT::c_stdCamera_temp && name == "temp_ccd") return newCallBack_temp(ipRecv);
1719  else if(derivedT::c_stdCamera_tempControl && name == "temp_ccd") return newCallBack_temp(ipRecv);
1720  else if(derivedT::c_stdCamera_tempControl && name == "temp_controller") return newCallBack_temp_controller(ipRecv);
1721  else if(derivedT::c_stdCamera_readoutSpeed && name == "readout_speed") return newCallBack_readoutSpeed(ipRecv);
1722  else if(derivedT::c_stdCamera_vShiftSpeed && name == "vshift_speed") return newCallBack_vShiftSpeed(ipRecv);
1723  else if(derivedT::c_stdCamera_emGain && name == "emgain") return newCallBack_emgain(ipRecv);
1724  else if(derivedT::c_stdCamera_exptimeCtrl && name == "exptime") return newCallBack_exptime(ipRecv);
1725  else if(derivedT::c_stdCamera_fpsCtrl && name == "fps") return newCallBack_fps(ipRecv);
1726  else if(derivedT::c_stdCamera_synchro && name == "synchro") return newCallBack_synchro(ipRecv);
1727  else if(derivedT::c_stdCamera_usesModes && name == "mode") return newCallBack_mode(ipRecv);
1728  else if(derivedT::c_stdCamera_cropMode && name == "roi_crop_mode") return newCallBack_cropMode(ipRecv);
1729  else if(derivedT::c_stdCamera_usesROI && name == "roi_region_x") return newCallBack_roi_x(ipRecv);
1730  else if(derivedT::c_stdCamera_usesROI && name == "roi_region_y") return newCallBack_roi_y(ipRecv);
1731  else if(derivedT::c_stdCamera_usesROI && name == "roi_region_w") return newCallBack_roi_w(ipRecv);
1732  else if(derivedT::c_stdCamera_usesROI && name == "roi_region_h") return newCallBack_roi_h(ipRecv);
1733  else if(derivedT::c_stdCamera_usesROI && name == "roi_region_bin_x") return newCallBack_roi_bin_x(ipRecv);
1734  else if(derivedT::c_stdCamera_usesROI && name == "roi_region_bin_y") return newCallBack_roi_bin_y(ipRecv);
1735  else if(derivedT::c_stdCamera_usesROI && name == "roi_region_check") return newCallBack_roi_check(ipRecv);
1736  else if(derivedT::c_stdCamera_usesROI && name == "roi_set") return newCallBack_roi_set(ipRecv);
1737  else if(derivedT::c_stdCamera_usesROI && name == "roi_set_full") return newCallBack_roi_full(ipRecv);
1738  else if(derivedT::c_stdCamera_usesROI && name == "roi_set_full_bin") return newCallBack_roi_fullbin(ipRecv);
1739  else if(derivedT::c_stdCamera_usesROI && name == "roi_load_last") return newCallBack_roi_loadlast(ipRecv);
1740  else if(derivedT::c_stdCamera_usesROI && name == "roi_set_last") return newCallBack_roi_last(ipRecv);
1741  else if(derivedT::c_stdCamera_usesROI && name == "roi_set_default") return newCallBack_roi_default(ipRecv);
1742  else if(derivedT::c_stdCamera_hasShutter && name == "shutter") return newCallBack_shutter(ipRecv);
1743 
1744  #ifndef XWCTEST_INDI_CALLBACK_VALIDATION
1745  derivedT::template log<software_error>({__FILE__,__LINE__, "unknown INDI property"});
1746  #endif
1747 
1748  return -1;
1749 }
1750 
1751 template<class derivedT>
1752 int stdCamera<derivedT>::setTempSetPt( const mx::meta::trueFalseT<true> & t)
1753 {
1754  static_cast<void>(t);
1755  return derived().setTempSetPt();
1756 }
1757 
1758 template<class derivedT>
1759 int stdCamera<derivedT>::setTempSetPt( const mx::meta::trueFalseT<false> & f)
1760 {
1761  static_cast<void>(f);
1762  return 0;
1763 }
1764 
1765 template<class derivedT>
1766 int stdCamera<derivedT>::newCallBack_temp( const pcf::IndiProperty &ipRecv )
1767 {
1768  if(derivedT::c_stdCamera_tempControl)
1769  {
1770  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
1771  return 0;
1772  #endif
1773 
1774  float target;
1775 
1776  std::unique_lock<std::mutex> lock(derived().m_indiMutex);
1777 
1778  if (derived().indiTargetUpdate(m_indiP_temp, target, ipRecv, true) < 0)
1779  {
1780  derivedT::template log<software_error>({__FILE__, __LINE__});
1781  return -1;
1782  }
1783 
1784  m_ccdTempSetpt = target;
1785 
1786  mx::meta::trueFalseT<derivedT::c_stdCamera_tempControl> tf;
1787  return setTempSetPt(tf);
1788  }
1789  else
1790  {
1791  return 0;
1792  }
1793 }
1794 
1795 template<class derivedT>
1796 int stdCamera<derivedT>::setTempControl( const mx::meta::trueFalseT<true> & t)
1797 {
1798  static_cast<void>(t);
1799  return derived().setTempControl();
1800 }
1801 
1802 template<class derivedT>
1803 int stdCamera<derivedT>::setTempControl( const mx::meta::trueFalseT<false> & f)
1804 {
1805  static_cast<void>(f);
1806  return 0;
1807 }
1808 
1809 template<class derivedT>
1811 {
1812  if(derivedT::c_stdCamera_tempControl)
1813  {
1814  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
1815  return 0;
1816  #endif
1817 
1818  if(!ipRecv.find("toggle")) return 0;
1819 
1820  m_tempControlStatusSet = false;
1821 
1822  std::unique_lock<std::mutex> lock(derived().m_indiMutex);
1823 
1824  if( ipRecv["toggle"].getSwitchState() == pcf::IndiElement::On)
1825  {
1826  m_tempControlStatusSet = true;
1827  derived().updateSwitchIfChanged(m_indiP_tempcont, "toggle", pcf::IndiElement::On, INDI_BUSY);
1828  }
1829  else if( ipRecv["toggle"].getSwitchState() == pcf::IndiElement::Off)
1830  {
1831  m_tempControlStatusSet = false;
1832  derived().updateSwitchIfChanged(m_indiP_tempcont, "toggle", pcf::IndiElement::Off, INDI_BUSY);
1833  }
1834 
1835  mx::meta::trueFalseT<derivedT::c_stdCamera_emGain> tf;
1836  return setTempControl(tf);
1837  }
1838  else
1839  {
1840  return 0;
1841  }
1842 }
1843 
1844 template<class derivedT>
1845 int stdCamera<derivedT>::setReadoutSpeed( const mx::meta::trueFalseT<true> & t)
1846 {
1847  static_cast<void>(t);
1848  return derived().setReadoutSpeed();
1849 }
1850 
1851 template<class derivedT>
1852 int stdCamera<derivedT>::setReadoutSpeed( const mx::meta::trueFalseT<false> & f)
1853 {
1854  static_cast<void>(f);
1855  return 0;
1856 }
1857 
1858 template<class derivedT>
1860 {
1861  if(derivedT::c_stdCamera_readoutSpeed)
1862  {
1863  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
1864  return 0;
1865  #endif
1866 
1867  std::unique_lock<std::mutex> lock(derived().m_indiMutex);
1868 
1869  std::string newspeed;
1870 
1871  for(size_t i=0; i< m_readoutSpeedNames.size(); ++i)
1872  {
1873  if(!ipRecv.find(m_readoutSpeedNames[i])) continue;
1874 
1875  if(ipRecv[m_readoutSpeedNames[i]].getSwitchState() == pcf::IndiElement::On)
1876  {
1877  if(newspeed != "")
1878  {
1879  derivedT::template log<text_log>("More than one readout speed selected", logPrio::LOG_ERROR);
1880  return -1;
1881  }
1882 
1883  newspeed = m_readoutSpeedNames[i];
1884  }
1885  }
1886 
1887  if(newspeed == "")
1888  {
1889  //We do a reset
1890  m_readoutSpeedNameSet = m_readoutSpeedName;
1891  }
1892  else
1893  {
1894  m_readoutSpeedNameSet = newspeed;
1895  }
1896 
1897  mx::meta::trueFalseT<derivedT::c_stdCamera_readoutSpeed> tf;
1898  return setReadoutSpeed(tf);
1899  }
1900 
1901  return 0;
1902 }
1903 
1904 template<class derivedT>
1905 int stdCamera<derivedT>::setVShiftSpeed( const mx::meta::trueFalseT<true> & t)
1906 {
1907  static_cast<void>(t);
1908  return derived().setVShiftSpeed();
1909 }
1910 
1911 template<class derivedT>
1912 int stdCamera<derivedT>::setVShiftSpeed( const mx::meta::trueFalseT<false> & f)
1913 {
1914  static_cast<void>(f);
1915  return 0;
1916 }
1917 
1918 template<class derivedT>
1920 {
1921  if(derivedT::c_stdCamera_vShiftSpeed)
1922  {
1923  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
1924  return 0;
1925  #endif
1926 
1927  std::unique_lock<std::mutex> lock(derived().m_indiMutex);
1928 
1929  std::string newspeed;
1930 
1931  for(size_t i=0; i< m_vShiftSpeedNames.size(); ++i)
1932  {
1933  if(!ipRecv.find(m_vShiftSpeedNames[i])) continue;
1934 
1935  if(ipRecv[m_vShiftSpeedNames[i]].getSwitchState() == pcf::IndiElement::On)
1936  {
1937  if(newspeed != "")
1938  {
1939  derivedT::template log<text_log>("More than one vShift speed selected", logPrio::LOG_ERROR);
1940  return -1;
1941  }
1942 
1943  newspeed = m_vShiftSpeedNames[i];
1944  }
1945  }
1946 
1947  if(newspeed == "")
1948  {
1949  //We do a reset
1950  m_vShiftSpeedNameSet = m_vShiftSpeedName;
1951  }
1952  else
1953  {
1954  m_vShiftSpeedNameSet = newspeed;
1955  }
1956 
1957  mx::meta::trueFalseT<derivedT::c_stdCamera_vShiftSpeed> tf;
1958  return setVShiftSpeed(tf);
1959  }
1960 
1961  return 0;
1962 }
1963 
1964 template<class derivedT>
1965 int stdCamera<derivedT>::setEMGain( const mx::meta::trueFalseT<true> & t)
1966 {
1967  static_cast<void>(t);
1968  return derived().setEMGain();
1969 }
1970 
1971 template<class derivedT>
1972 int stdCamera<derivedT>::setEMGain( const mx::meta::trueFalseT<false> & f)
1973 {
1974  static_cast<void>(f);
1975  return 0;
1976 }
1977 
1978 template<class derivedT>
1979 int stdCamera<derivedT>::newCallBack_emgain( const pcf::IndiProperty &ipRecv)
1980 {
1981  if(derivedT::c_stdCamera_emGain)
1982  {
1983  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
1984  return 0;
1985  #endif
1986 
1987  float target;
1988 
1989  std::unique_lock<std::mutex> lock(derived().m_indiMutex);
1990 
1991  if( derived().indiTargetUpdate( m_indiP_emGain, target, ipRecv, true) < 0)
1992  {
1993  derivedT::template log<software_error>({__FILE__,__LINE__});
1994  return -1;
1995  }
1996 
1997  m_emGainSet = target;
1998 
1999  mx::meta::trueFalseT<derivedT::c_stdCamera_emGain> tf;
2000  return setEMGain(tf);
2001  }
2002 
2003  return 0;
2004 }
2005 
2006 template<class derivedT>
2007 int stdCamera<derivedT>::setExpTime( const mx::meta::trueFalseT<true> & t)
2008 {
2009  static_cast<void>(t);
2010  return derived().setExpTime();
2011 }
2012 
2013 template<class derivedT>
2014 int stdCamera<derivedT>::setExpTime( const mx::meta::trueFalseT<false> & f)
2015 {
2016  static_cast<void>(f);
2017  return 0;
2018 }
2019 
2020 template<class derivedT>
2021 int stdCamera<derivedT>::newCallBack_exptime( const pcf::IndiProperty &ipRecv)
2022 {
2023  if(derivedT::c_stdCamera_exptimeCtrl)
2024  {
2025  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2026  return 0;
2027  #endif
2028 
2029  float target;
2030 
2031  std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2032 
2033  if( derived().indiTargetUpdate( m_indiP_exptime, target, ipRecv, true) < 0)
2034  {
2035  derivedT::template log<software_error>({__FILE__,__LINE__});
2036  return -1;
2037  }
2038 
2039  m_expTimeSet = target;
2040 
2041  mx::meta::trueFalseT<derivedT::c_stdCamera_exptimeCtrl> tf;
2042  return setExpTime(tf);
2043  }
2044 
2045  return 0;
2046 }
2047 
2048 template<class derivedT>
2049 int stdCamera<derivedT>::setFPS( const mx::meta::trueFalseT<true> & t)
2050 {
2051  static_cast<void>(t);
2052  return derived().setFPS();
2053 }
2054 
2055 template<class derivedT>
2056 int stdCamera<derivedT>::setFPS( const mx::meta::trueFalseT<false> & f)
2057 {
2058  static_cast<void>(f);
2059  return 0;
2060 }
2061 
2062 template<class derivedT>
2063 int stdCamera<derivedT>::newCallBack_fps( const pcf::IndiProperty &ipRecv)
2064 {
2065  if(derivedT::c_stdCamera_fpsCtrl)
2066  {
2067  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2068  return 0;
2069  #endif
2070 
2071  float target;
2072 
2073  std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2074 
2075  if( derived().indiTargetUpdate( m_indiP_fps, target, ipRecv, true) < 0)
2076  {
2077  derivedT::template log<software_error>({__FILE__,__LINE__});
2078  return -1;
2079  }
2080 
2081  m_fpsSet = target;
2082 
2083  mx::meta::trueFalseT<derivedT::c_stdCamera_fpsCtrl> tf;
2084  return setFPS(tf);
2085  }
2086 
2087  return 0;
2088 }
2089 
2090 template<class derivedT>
2091 int stdCamera<derivedT>::setSynchro( const mx::meta::trueFalseT<true> & t)
2092 {
2093  static_cast<void>(t);
2094  return derived().setSynchro();
2095 }
2096 
2097 template<class derivedT>
2098 int stdCamera<derivedT>::setSynchro( const mx::meta::trueFalseT<false> & f)
2099 {
2100  static_cast<void>(f);
2101  return 0;
2102 }
2103 
2104 template<class derivedT>
2105 int stdCamera<derivedT>::newCallBack_synchro( const pcf::IndiProperty &ipRecv)
2106 {
2107  if(derivedT::c_stdCamera_synchro)
2108  {
2109  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2110  return 0;
2111  #endif
2112 
2113  if(!ipRecv.find("toggle")) return 0;
2114 
2115  if( ipRecv["toggle"].getSwitchState() == pcf::IndiElement::Off )
2116  {
2117  m_synchroSet = false;
2118  }
2119 
2120  if( ipRecv["toggle"].getSwitchState() == pcf::IndiElement::On )
2121  {
2122  m_synchroSet = true;
2123  }
2124 
2125  std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2126 
2127  mx::meta::trueFalseT<derivedT::c_stdCamera_synchro> tf;
2128  return setSynchro(tf);
2129  }
2130 
2131  return 0;
2132 }
2133 
2134 template<class derivedT>
2135 int stdCamera<derivedT>::newCallBack_mode( const pcf::IndiProperty &ipRecv )
2136 {
2137  if(derivedT::c_stdCamera_usesModes)
2138  {
2139  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2140  return 0;
2141  #endif
2142 
2143  std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2144 
2145  if(ipRecv.getName() != m_indiP_mode.getName())
2146  {
2147  derivedT::template log<software_error>({__FILE__, __LINE__, "invalid indi property received"});
2148  return -1;
2149  }
2150 
2151  //look for selected mode switch which matches a known mode. Make sure only one is selected.
2152  std::string newName = "";
2153  for(auto it=m_cameraModes.begin(); it != m_cameraModes.end(); ++it)
2154  {
2155  if(!ipRecv.find(it->first)) continue;
2156 
2157  if(ipRecv[it->first].getSwitchState() == pcf::IndiElement::On)
2158  {
2159  if(newName != "")
2160  {
2161  derivedT::template log<text_log>("More than one camera mode selected", logPrio::LOG_ERROR);
2162  return -1;
2163  }
2164 
2165  newName = it->first;
2166  }
2167  }
2168 
2169  if(newName == "")
2170  {
2171  return 0;
2172  }
2173 
2174  //Now signal the f.g. thread to reconfigure
2175  m_nextMode = newName;
2176  derived().m_reconfig = true;
2177 
2178  return 0;
2179  }
2180  else
2181  {
2182  return 0;
2183  }
2184 }
2185 
2186 template<class derivedT>
2188 {
2189  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2190  return 0;
2191  #endif
2192 
2193  if(!ipRecv.find("request")) return 0;
2194 
2195  if( ipRecv["request"].getSwitchState() == pcf::IndiElement::On)
2196  {
2197  std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2198 
2199  indi::updateSwitchIfChanged(m_indiP_reconfig, "request", pcf::IndiElement::Off, derived().m_indiDriver, INDI_IDLE);
2200 
2201  m_nextMode = m_modeName;
2202  derived().m_reconfig = true;
2203  return 0;
2204  }
2205 
2206  return 0;
2207 }
2208 
2209 template<class derivedT>
2210 int stdCamera<derivedT>::setCropMode( const mx::meta::trueFalseT<true> & t)
2211 {
2212  static_cast<void>(t);
2213  return derived().setCropMode();
2214 }
2215 
2216 template<class derivedT>
2217 int stdCamera<derivedT>::setCropMode( const mx::meta::trueFalseT<false> & f)
2218 {
2219  static_cast<void>(f);
2220  return 0;
2221 }
2222 
2223 template<class derivedT>
2225 {
2226  if(derivedT::c_stdCamera_cropMode)
2227  {
2228  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2229  return 0;
2230  #endif
2231 
2232  if(!ipRecv.find("toggle")) return 0;
2233 
2234  if( ipRecv["toggle"].getSwitchState() == pcf::IndiElement::Off )
2235  {
2236  m_cropModeSet = false;
2237  }
2238 
2239  if( ipRecv["toggle"].getSwitchState() == pcf::IndiElement::On )
2240  {
2241  m_cropModeSet = true;
2242  }
2243 
2244  std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2245 
2246  mx::meta::trueFalseT<derivedT::c_stdCamera_cropMode> tf;
2247  return setCropMode(tf);
2248  }
2249 
2250  return 0;
2251 }
2252 
2253 ///\todo why don't these check if usesROI is true?
2254 template<class derivedT>
2255 int stdCamera<derivedT>::newCallBack_roi_x( const pcf::IndiProperty &ipRecv )
2256 {
2257  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2258  return 0;
2259  #endif
2260 
2261  float target;
2262 
2263  std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2264 
2265  if( derived().indiTargetUpdate( m_indiP_roi_x, target, ipRecv, false) < 0)
2266  {
2267  m_nextROI.x = m_currentROI.x;
2268  derivedT::template log<software_error>({__FILE__,__LINE__});
2269  return -1;
2270  }
2271 
2272  m_nextROI.x = target;
2273 
2274  return 0;
2275 }
2276 
2277 template<class derivedT>
2278 int stdCamera<derivedT>::newCallBack_roi_y( const pcf::IndiProperty &ipRecv )
2279 {
2280  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2281  return 0;
2282  #endif
2283 
2284  float target;
2285 
2286  std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2287 
2288  if( derived().indiTargetUpdate( m_indiP_roi_y, target, ipRecv, false) < 0)
2289  {
2290  m_nextROI.y = m_currentROI.y;
2291  derivedT::template log<software_error>({__FILE__,__LINE__});
2292  return -1;
2293  }
2294 
2295  m_nextROI.y = target;
2296 
2297  return 0;
2298 }
2299 
2300 template<class derivedT>
2301 int stdCamera<derivedT>::newCallBack_roi_w( const pcf::IndiProperty &ipRecv )
2302 {
2303  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2304  return 0;
2305  #endif
2306 
2307  int target;
2308 
2309  std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2310 
2311  if( derived().indiTargetUpdate( m_indiP_roi_w, target, ipRecv, false) < 0)
2312  {
2313  m_nextROI.w = m_currentROI.w;
2314  derivedT::template log<software_error>({__FILE__,__LINE__});
2315  return -1;
2316  }
2317 
2318  m_nextROI.w = target;
2319 
2320  return 0;
2321 }
2322 
2323 template<class derivedT>
2324 int stdCamera<derivedT>::newCallBack_roi_h( const pcf::IndiProperty &ipRecv )
2325 {
2326  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2327  return 0;
2328  #endif
2329 
2330  int target;
2331 
2332  std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2333 
2334  if( derived().indiTargetUpdate( m_indiP_roi_h, target, ipRecv, false) < 0)
2335  {
2336  derivedT::template log<software_error>({__FILE__,__LINE__});
2337  m_nextROI.h = m_currentROI.h;
2338  return -1;
2339  }
2340 
2341  m_nextROI.h = target;
2342 
2343  return 0;
2344 }
2345 
2346 template<class derivedT>
2347 int stdCamera<derivedT>::newCallBack_roi_bin_x ( const pcf::IndiProperty &ipRecv )
2348 {
2349  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2350  return 0;
2351  #endif
2352 
2353  int target;
2354 
2355  std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2356 
2357  if( derived().indiTargetUpdate( m_indiP_roi_bin_x, target, ipRecv, false) < 0)
2358  {
2359  derivedT::template log<software_error>({__FILE__,__LINE__});
2360  m_nextROI.bin_x = m_currentROI.bin_x;
2361  return -1;
2362  }
2363 
2364  m_nextROI.bin_x = target;
2365 
2366  return 0;
2367 }
2368 
2369 template<class derivedT>
2371 {
2372  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2373  return 0;
2374  #endif
2375 
2376  int target;
2377 
2378  std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2379 
2380  if( derived().indiTargetUpdate( m_indiP_roi_bin_y, target, ipRecv, false) < 0)
2381  {
2382  derivedT::template log<software_error>({__FILE__,__LINE__});
2383  m_nextROI.bin_y = m_currentROI.bin_y;
2384  return -1;
2385  }
2386 
2387  m_nextROI.bin_y = target;
2388 
2389  return 0;
2390 }
2391 
2392 template<class derivedT>
2393 int stdCamera<derivedT>::checkNextROI( const mx::meta::trueFalseT<true> & t)
2394 {
2395  static_cast<void>(t);
2396  return derived().checkNextROI();
2397 }
2398 
2399 template<class derivedT>
2400 int stdCamera<derivedT>::checkNextROI( const mx::meta::trueFalseT<false> & f)
2401 {
2402  static_cast<void>(f);
2403  return 0;
2404 }
2405 
2406 template<class derivedT>
2408 {
2409  if(derivedT::c_stdCamera_usesROI)
2410  {
2411  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2412  return 0;
2413  #endif
2414 
2415  if(!ipRecv.find("request")) return 0;
2416 
2417  if( ipRecv["request"].getSwitchState() == pcf::IndiElement::On)
2418  {
2419  std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2420 
2421  indi::updateSwitchIfChanged(m_indiP_roi_check, "request", pcf::IndiElement::Off, derived().m_indiDriver, INDI_IDLE);
2422 
2423  mx::meta::trueFalseT<derivedT::c_stdCamera_usesROI> tf;
2424  return checkNextROI(tf);
2425  }
2426 
2427  return 0;
2428  }
2429 
2430  return 0;
2431 }
2432 
2433 template<class derivedT>
2434 int stdCamera<derivedT>::setNextROI( const mx::meta::trueFalseT<true> & t)
2435 {
2436  static_cast<void>(t);
2437  return derived().setNextROI();
2438 }
2439 
2440 template<class derivedT>
2441 int stdCamera<derivedT>::setNextROI( const mx::meta::trueFalseT<false> & f)
2442 {
2443  static_cast<void>(f);
2444  return 0;
2445 }
2446 
2447 template<class derivedT>
2448 int stdCamera<derivedT>::newCallBack_roi_set( const pcf::IndiProperty &ipRecv )
2449 {
2450  if(derivedT::c_stdCamera_usesROI)
2451  {
2452  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2453  return 0;
2454  #endif
2455 
2456  if(!ipRecv.find("request")) return 0;
2457 
2458  if( ipRecv["request"].getSwitchState() == pcf::IndiElement::On)
2459  {
2460  std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2461 
2462  indi::updateSwitchIfChanged(m_indiP_roi_set, "request", pcf::IndiElement::Off, derived().m_indiDriver, INDI_IDLE);
2463 
2464  m_lastROI = m_currentROI;
2465 
2466  mx::meta::trueFalseT<derivedT::c_stdCamera_usesROI> tf;
2467  return setNextROI(tf);
2468  }
2469 
2470  return 0;
2471  }
2472 
2473  return 0;
2474 }
2475 
2476 template<class derivedT>
2477 int stdCamera<derivedT>::newCallBack_roi_full( const pcf::IndiProperty &ipRecv )
2478 {
2479  if(derivedT::c_stdCamera_usesROI)
2480  {
2481  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2482  return 0;
2483  #endif
2484 
2485  if(!ipRecv.find("request")) return 0;
2486 
2487  if( ipRecv["request"].getSwitchState() == pcf::IndiElement::On)
2488  {
2489  std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2490 
2491  indi::updateSwitchIfChanged(m_indiP_roi_full, "request", pcf::IndiElement::Off, derived().m_indiDriver, INDI_IDLE);
2492 
2493  m_nextROI.x = m_full_x;
2494  m_nextROI.y = m_full_y;
2495  m_nextROI.w = m_full_w;
2496  m_nextROI.h = m_full_h;
2497  m_nextROI.bin_x = m_full_bin_x;
2498  m_nextROI.bin_y = m_full_bin_y;
2499  m_lastROI = m_currentROI;
2500  mx::meta::trueFalseT<derivedT::c_stdCamera_usesROI> tf;
2501  return setNextROI(tf);
2502  }
2503 
2504  return 0;
2505  }
2506 
2507  return 0;
2508 }
2509 
2510 template<class derivedT>
2512 {
2513  if(derivedT::c_stdCamera_usesROI)
2514  {
2515  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2516  return 0;
2517  #endif
2518 
2519  if(!ipRecv.find("request")) return 0;
2520 
2521  if( ipRecv["request"].getSwitchState() == pcf::IndiElement::On)
2522  {
2523  std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2524 
2525  indi::updateSwitchIfChanged(m_indiP_roi_fullbin, "request", pcf::IndiElement::Off, derived().m_indiDriver, INDI_IDLE);
2526 
2527  bool reset = false;
2528 
2529  if(m_full_currbin_x == 0) //still defaulted
2530  {
2531  derivedT::template log<text_log>("current-binning full ROI not implemented for this camera", logPrio::LOG_WARNING);
2532  m_full_currbin_x = m_full_x;
2533  m_full_currbin_y = m_full_y;
2534  m_full_currbin_w = m_full_w;
2535  m_full_currbin_h = m_full_h;
2536  reset = true;
2537  }
2538 
2539 
2540 
2541  m_nextROI.x = m_full_currbin_x;
2542  m_nextROI.y = m_full_currbin_y;
2543  m_nextROI.w = m_full_currbin_w;
2544  m_nextROI.h = m_full_currbin_h;
2545  if(reset)
2546  {
2547  //Use full binning
2548  m_nextROI.bin_x = m_full_bin_x;
2549  m_nextROI.bin_y = m_full_bin_y;
2550 
2551  //restore defaults for next time
2552  m_full_currbin_x = 0;
2553  m_full_currbin_y = 0;
2554  m_full_currbin_w = 0;
2555  m_full_currbin_h = 0;
2556  }
2557  else
2558  {
2559  m_nextROI.bin_x = m_currentROI.bin_x;
2560  m_nextROI.bin_y = m_currentROI.bin_y;
2561  }
2562 
2563  m_lastROI = m_currentROI;
2564  mx::meta::trueFalseT<derivedT::c_stdCamera_usesROI> tf;
2565  return setNextROI(tf);
2566  }
2567 
2568  return 0;
2569  }
2570 
2571  return 0;
2572 }
2573 
2574 template<class derivedT>
2576 {
2577  if(derivedT::c_stdCamera_usesROI)
2578  {
2579  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2580  return 0;
2581  #endif
2582 
2583  if(!ipRecv.find("request")) return 0;
2584 
2585  if( ipRecv["request"].getSwitchState() == pcf::IndiElement::On)
2586  {
2587  std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2588 
2589  indi::updateSwitchIfChanged(m_indiP_roi_loadlast, "request", pcf::IndiElement::Off, derived().m_indiDriver, INDI_IDLE);
2590 
2591  m_nextROI = m_lastROI;
2592  return 0;
2593  }
2594 
2595  return 0;
2596  }
2597 
2598  return 0;
2599 }
2600 
2601 template<class derivedT>
2602 int stdCamera<derivedT>::newCallBack_roi_last( const pcf::IndiProperty &ipRecv )
2603 {
2604  if(derivedT::c_stdCamera_usesROI)
2605  {
2606  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2607  return 0;
2608  #endif
2609  if(!ipRecv.find("request")) return 0;
2610 
2611  if( ipRecv["request"].getSwitchState() == pcf::IndiElement::On)
2612  {
2613  std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2614 
2615  indi::updateSwitchIfChanged(m_indiP_roi_last, "request", pcf::IndiElement::Off, derived().m_indiDriver, INDI_IDLE);
2616 
2617  m_nextROI = m_lastROI;
2618  m_lastROI = m_currentROI;
2619  mx::meta::trueFalseT<derivedT::c_stdCamera_usesROI> tf;
2620  return setNextROI(tf);
2621  }
2622 
2623  return 0;
2624  }
2625 
2626  return 0;
2627 }
2628 
2629 template<class derivedT>
2631 {
2632  if(derivedT::c_stdCamera_usesROI)
2633  {
2634  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2635  return 0;
2636  #endif
2637 
2638  if(!ipRecv.find("request")) return 0;
2639 
2640  if( ipRecv["request"].getSwitchState() == pcf::IndiElement::On)
2641  {
2642  std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2643 
2644  indi::updateSwitchIfChanged(m_indiP_roi_default, "request", pcf::IndiElement::Off, derived().m_indiDriver, INDI_IDLE);
2645 
2646  m_nextROI.x = m_default_x;
2647  m_nextROI.y = m_default_y;
2648  m_nextROI.w = m_default_w;
2649  m_nextROI.h = m_default_h;
2650  m_nextROI.bin_x = m_default_bin_x;
2651  m_nextROI.bin_y = m_default_bin_y;
2652  m_lastROI = m_currentROI;
2653  mx::meta::trueFalseT<derivedT::c_stdCamera_usesROI> tf;
2654  return setNextROI(tf);
2655  }
2656 
2657  return 0;
2658  }
2659 
2660  return 0;
2661 }
2662 
2663 template<class derivedT>
2665  const mx::meta::trueFalseT<true> & t
2666  )
2667 {
2668  static_cast<void>(t);
2669  return derived().setShutter(ss);
2670 }
2671 
2672 template<class derivedT>
2674  const mx::meta::trueFalseT<false> & f
2675  )
2676 {
2677  static_cast<void>(ss);
2678  static_cast<void>(f);
2679  return 0;
2680 }
2681 
2682 template<class derivedT>
2683 int stdCamera<derivedT>::newCallBack_shutter( const pcf::IndiProperty &ipRecv )
2684 {
2685  if(derivedT::c_stdCamera_hasShutter)
2686  {
2687  #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2688  return 0;
2689  #endif
2690 
2691  if(!ipRecv.find("toggle")) return 0;
2692 
2693  mx::meta::trueFalseT<derivedT::c_stdCamera_hasShutter> tf;
2694 
2695  if( ipRecv["toggle"].getSwitchState() == pcf::IndiElement::Off )
2696  {
2697  setShutter(1, tf);
2698  }
2699 
2700  if( ipRecv["toggle"].getSwitchState() == pcf::IndiElement::On )
2701  {
2702  setShutter(0, tf);
2703  }
2704 
2705  return 0;
2706  }
2707  return 0;
2708 }
2709 
2710 template<class derivedT>
2711 std::string stdCamera<derivedT>::stateString( const mx::meta::trueFalseT<true> & t)
2712 {
2713  static_cast<void>(t);
2714  return derived().stateString();
2715 }
2716 
2717 template<class derivedT>
2718 std::string stdCamera<derivedT>::stateString( const mx::meta::trueFalseT<false> & f)
2719 {
2720  static_cast<void>(f);
2721  return "";
2722 }
2723 
2724 template<class derivedT>
2725 bool stdCamera<derivedT>::stateStringValid( const mx::meta::trueFalseT<true> & t)
2726 {
2727  static_cast<void>(t);
2728  return derived().stateStringValid();
2729 }
2730 
2731 template<class derivedT>
2732 bool stdCamera<derivedT>::stateStringValid( const mx::meta::trueFalseT<false> & f)
2733 {
2734  static_cast<void>(f);
2735  return false;
2736 }
2737 
2738 template<class derivedT>
2740 {
2741  if( !derived().m_indiDriver ) return 0;
2742 
2743  if(derivedT::c_stdCamera_readoutSpeed)
2744  {
2745  indi::updateSelectionSwitchIfChanged( m_indiP_readoutSpeed, m_readoutSpeedName, derived().m_indiDriver, INDI_OK);
2746  }
2747 
2748  if(derivedT::c_stdCamera_vShiftSpeed)
2749  {
2750  indi::updateSelectionSwitchIfChanged( m_indiP_vShiftSpeed, m_vShiftSpeedName, derived().m_indiDriver, INDI_OK);
2751  }
2752 
2753  if(derivedT::c_stdCamera_emGain)
2754  {
2755  derived().updateIfChanged(m_indiP_emGain, "current", m_emGain, INDI_IDLE);
2756  derived().updateIfChanged(m_indiP_emGain, "target", m_emGainSet, INDI_IDLE);
2757  }
2758 
2759  if(derivedT::c_stdCamera_exptimeCtrl)
2760  {
2761  derived().updateIfChanged(m_indiP_exptime, "current", m_expTime, INDI_IDLE);
2762  derived().updateIfChanged(m_indiP_exptime, "target", m_expTimeSet, INDI_IDLE);
2763  }
2764 
2765  if(derivedT::c_stdCamera_fpsCtrl)
2766  {
2767  derived().updateIfChanged(m_indiP_fps, "current", m_fps, INDI_IDLE);
2768  derived().updateIfChanged(m_indiP_fps, "target", m_fpsSet, INDI_IDLE);
2769  }
2770  else if(derivedT::c_stdCamera_fps)
2771  {
2772  derived().updateIfChanged(m_indiP_fps, "current", m_fps, INDI_IDLE);
2773  }
2774 
2775  if(derivedT::c_stdCamera_synchro)
2776  {
2777  if(m_synchro == false)
2778  {
2779  derived().updateSwitchIfChanged(m_indiP_synchro, "toggle", pcf::IndiElement::Off, INDI_IDLE);
2780  }
2781  else
2782  {
2783  derived().updateSwitchIfChanged(m_indiP_synchro, "toggle", pcf::IndiElement::On, INDI_OK);
2784  }
2785  }
2786 
2787  if(derivedT::c_stdCamera_usesModes)
2788  {
2789  auto st = pcf::IndiProperty::Ok;
2790  if(m_nextMode != "") st = pcf::IndiProperty::Busy;
2791 
2792  for(auto it = m_cameraModes.begin();it!=m_cameraModes.end();++it)
2793  {
2794  if(it->first == m_modeName) derived().updateSwitchIfChanged(m_indiP_mode, it->first, pcf::IndiElement::On, st);
2795  else derived().updateSwitchIfChanged(m_indiP_mode, it->first, pcf::IndiElement::Off, st);
2796  }
2797 
2798  }
2799 
2800  if(derivedT::c_stdCamera_cropMode)
2801  {
2802  if(m_cropMode == false)
2803  {
2804  derived().updateSwitchIfChanged(m_indiP_cropMode, "toggle", pcf::IndiElement::Off, INDI_IDLE);
2805  }
2806  else
2807  {
2808  derived().updateSwitchIfChanged(m_indiP_cropMode, "toggle", pcf::IndiElement::On, INDI_OK);
2809  }
2810  }
2811 
2812  if(derivedT::c_stdCamera_usesROI)
2813  {
2814  //These can't change after initialization, but might not be discoverable until powered on and connected.
2815  //so we'll check every time I guess.
2816  derived().updateIfChanged(m_indiP_fullROI, "x", m_full_x, INDI_IDLE);
2817  derived().updateIfChanged(m_indiP_fullROI, "y", m_full_y, INDI_IDLE);
2818  derived().updateIfChanged(m_indiP_fullROI, "w", m_full_w, INDI_IDLE);
2819  derived().updateIfChanged(m_indiP_fullROI, "h", m_full_h, INDI_IDLE);
2820  }
2821 
2822  if(derivedT::c_stdCamera_tempControl)
2823  {
2824  if(m_tempControlStatus == false)
2825  {
2826  derived().updateSwitchIfChanged( m_indiP_tempcont, "toggle", pcf::IndiElement::Off, INDI_IDLE);
2827  derived().updateIfChanged(m_indiP_temp, "current", m_ccdTemp, INDI_IDLE);
2828  derived().updateIfChanged(m_indiP_temp, "target", m_ccdTempSetpt, INDI_IDLE);
2829  derived().updateIfChanged( m_indiP_tempstat, "status", m_tempControlStatusStr, INDI_IDLE);
2830  }
2831  else
2832  {
2833  if(m_tempControlOnTarget)
2834  {
2835  derived().updateSwitchIfChanged( m_indiP_tempcont, "toggle", pcf::IndiElement::On, INDI_OK);
2836  derived().updateIfChanged(m_indiP_temp, "current", m_ccdTemp, INDI_OK);
2837  derived().updateIfChanged(m_indiP_temp, "target", m_ccdTempSetpt, INDI_OK);
2838  derived().updateIfChanged( m_indiP_tempstat, "status", m_tempControlStatusStr, INDI_OK);
2839  }
2840  else
2841  {
2842  derived().updateSwitchIfChanged( m_indiP_tempcont, "toggle", pcf::IndiElement::On, INDI_BUSY);
2843  derived().updateIfChanged(m_indiP_temp, "current", m_ccdTemp, INDI_BUSY);
2844  derived().updateIfChanged(m_indiP_temp, "target", m_ccdTempSetpt, INDI_BUSY);
2845  derived().updateIfChanged( m_indiP_tempstat, "status", m_tempControlStatusStr, INDI_BUSY);
2846  }
2847  }
2848  }
2849  else if(derivedT::c_stdCamera_temp)
2850  {
2851  derived().updateIfChanged(m_indiP_temp, "current", m_ccdTemp, INDI_IDLE);
2852  }
2853 
2854 
2855 
2856  if(derivedT::c_stdCamera_hasShutter)
2857  {
2858  if(m_shutterStatus == "OPERATING")
2859  {
2860  derived().updateIfChanged(m_indiP_shutterStatus, "status", m_shutterStatus, INDI_BUSY);
2861  }
2862  if(m_shutterStatus == "POWERON" || m_shutterStatus == "READY")
2863  {
2864  derived().updateIfChanged(m_indiP_shutterStatus, "status", m_shutterStatus, INDI_IDLE);
2865  }
2866  else
2867  {
2868  derived().updateIfChanged(m_indiP_shutterStatus, "status", m_shutterStatus, INDI_IDLE);
2869  }
2870 
2871  if(m_shutterState == 0) //0 shut, 1 open
2872  {
2873  derived().updateSwitchIfChanged(m_indiP_shutter, "toggle", pcf::IndiElement::On, INDI_OK);
2874  }
2875  else
2876  {
2877  derived().updateSwitchIfChanged(m_indiP_shutter, "toggle", pcf::IndiElement::Off, INDI_IDLE);
2878  }
2879  }
2880 
2881  if(derivedT::c_stdCamera_usesStateString)
2882  {
2883  mx::meta::trueFalseT<derivedT::c_stdCamera_usesStateString> tf;
2884  derived().updateIfChanged(m_indiP_stateString, "current", stateString(tf), INDI_IDLE);
2885  if(stateStringValid(tf))
2886  {
2887  derived().updateIfChanged(m_indiP_stateString, "valid", "yes", INDI_IDLE);
2888  }
2889  else
2890  {
2891  derived().updateIfChanged(m_indiP_stateString, "valid", "no", INDI_IDLE);
2892  }
2893  }
2894  return 0;
2895 }
2896 
2897 template<class derivedT>
2899 {
2900  static std::string last_mode;
2901  static roi last_roi;
2902  static float last_expTime = -1e30; //ensure first one goes
2903  static float last_fps = 0;
2904  static float last_adcSpeed = -1;
2905  static float last_emGain = -1;
2906  static float last_ccdTemp = 0;
2907  static float last_ccdTempSetpt = 0;
2908  static bool last_tempControlStatus = 0;
2909  static bool last_tempControlOnTarget = 0;
2910  static std::string last_tempControlStatusStr;
2911  static std::string last_shutterStatus;
2912  static int last_shutterState = false;
2913  static bool last_synchro = false;
2914  static float last_vshiftSpeed = -1;
2915  static bool last_cropMode = false;
2916 
2917 
2918  if(force || m_modeName != last_mode ||
2919  m_currentROI.x != last_roi.x ||
2920  m_currentROI.y != last_roi.y ||
2921  m_currentROI.w != last_roi.w ||
2922  m_currentROI.h != last_roi.h ||
2923  m_currentROI.bin_x != last_roi.bin_x ||
2924  m_currentROI.bin_y != last_roi.bin_y ||
2925  m_expTime != last_expTime ||
2926  m_fps != last_fps ||
2927  m_emGain != last_emGain ||
2928  m_adcSpeed != last_adcSpeed ||
2929  m_ccdTemp != last_ccdTemp ||
2930  m_ccdTempSetpt != last_ccdTempSetpt ||
2931  m_tempControlStatus != last_tempControlStatus ||
2932  m_tempControlOnTarget != last_tempControlOnTarget ||
2933  m_tempControlStatusStr != last_tempControlStatusStr ||
2934  m_shutterStatus != last_shutterStatus ||
2935  m_shutterState != last_shutterState ||
2936  m_synchro != last_synchro ||
2937  m_vshiftSpeed != last_vshiftSpeed ||
2938  m_cropMode != last_cropMode)
2939  {
2940  derived().template telem<telem_stdcam>({m_modeName, m_currentROI.x, m_currentROI.y,
2941  m_currentROI.w, m_currentROI.h, m_currentROI.bin_x, m_currentROI.bin_y,
2942  m_expTime, m_fps, m_emGain, m_adcSpeed, m_ccdTemp, m_ccdTempSetpt, (uint8_t) m_tempControlStatus,
2943  (uint8_t) m_tempControlOnTarget, m_tempControlStatusStr, m_shutterStatus, (int8_t) m_shutterState,
2944  (uint8_t) m_synchro, m_vshiftSpeed, (uint8_t) m_cropMode});
2945 
2946  last_mode = m_modeName;
2947  last_roi = m_currentROI;
2948  last_expTime = m_expTime;
2949  last_fps = m_fps;
2950  last_emGain = m_emGain;
2951  last_adcSpeed = m_adcSpeed;
2952  last_ccdTemp = m_ccdTemp;
2953  last_ccdTempSetpt = m_ccdTempSetpt;
2954  last_tempControlStatus = m_tempControlStatus;
2955  last_tempControlOnTarget = m_tempControlOnTarget;
2956  last_tempControlStatusStr = m_tempControlStatusStr;
2957  last_shutterStatus = m_shutterStatus;
2958  last_shutterState = m_shutterState;
2959  last_synchro = m_synchro;
2960  last_vshiftSpeed = m_vshiftSpeed;
2961  last_cropMode = m_cropMode;
2962  }
2963 
2964 
2965  return 0;
2966 
2967 }
2968 
2969 
2970 } //namespace dev
2971 } //namespace app
2972 } //namespace MagAOX
2973 
2974 #endif //stdCamera_hpp
MagAO-X standard camera interface.
Definition: stdCamera.hpp:232
float m_maxEMGain
The configurable maximum EM gain. To be enforced in derivedT.
Definition: stdCamera.hpp:296
std::vector< std::string > m_readoutSpeedNames
Definition: stdCamera.hpp:279
float m_minExpTime
The minimum exposure time, used for INDI attributes.
Definition: stdCamera.hpp:308
pcf::IndiProperty m_indiP_roi_fullbin
Property used to trigger setting the full in current binning ROI.
Definition: stdCamera.hpp:428
float m_fpsSet
The commanded fps, as set by user.
Definition: stdCamera.hpp:320
int newCallBack_temp(const pcf::IndiProperty &ipRecv)
Callback to process a NEW CCD temp request.
Definition: stdCamera.hpp:1766
int newCallBack_cropMode(const pcf::IndiProperty &ipRecv)
Callback to process a NEW cropMode request.
Definition: stdCamera.hpp:2224
bool m_synchroSet
Target status of m_synchro.
Definition: stdCamera.hpp:331
pcf::IndiProperty m_indiP_roi_y
Property used to set the ROI x center coordinate.
Definition: stdCamera.hpp:415
int createReadoutSpeed(const mx::meta::trueFalseT< true > &t)
Definition: stdCamera.hpp:1069
int m_full_currbin_w
The current-binning full ROI width.
Definition: stdCamera.hpp:411
int setShutter(int ss, const mx::meta::trueFalseT< true > &t)
Interface to setShutter when the derivedT has a shutter.
Definition: stdCamera.hpp:2664
float m_default_x
Power-on ROI center x coordinate.
Definition: stdCamera.hpp:395
std::string m_tempControlStatusStr
Camera specific description of temperature control status.
Definition: stdCamera.hpp:267
float m_emGain
The camera's current EM gain (if available).
Definition: stdCamera.hpp:294
int m_full_bin_x
The x-binning in the full ROI.
Definition: stdCamera.hpp:406
int newCallBack_readoutSpeed(const pcf::IndiProperty &ipRecv)
Callback to process a NEW readout speed request.
Definition: stdCamera.hpp:1859
std::vector< std::string > m_readoutSpeedNameLabels
Definition: stdCamera.hpp:280
float m_full_currbin_x
The current-binning full ROI center x coordinate.
Definition: stdCamera.hpp:409
int m_full_w
The full ROI width.
Definition: stdCamera.hpp:404
float m_emGainSet
The camera's EM gain, as set by the user.
Definition: stdCamera.hpp:295
std::string m_vShiftSpeedNameSet
The user requested vshift speed name, to be set by derived()
Definition: stdCamera.hpp:289
bool m_cropModeSet
Desired status of crop mode ROIs, if enabled for this camera.
Definition: stdCamera.hpp:440
int newCallBack_roi_bin_y(const pcf::IndiProperty &ipRecv)
Callback to process a NEW bin_y request.
Definition: stdCamera.hpp:2370
std::string m_defaultReadoutSpeed
The default readout speed of the camera.
Definition: stdCamera.hpp:245
pcf::IndiProperty m_indiP_shutterStatus
State of the shutter. 0 = shut, 1 = open, -1 = unknown.
Definition: stdCamera.hpp:452
float m_expTime
The current exposure time, in seconds.
Definition: stdCamera.hpp:312
int setExpTime(const mx::meta::trueFalseT< true > &t)
Interface to setExpTime when the derivedT uses exposure time controls.
Definition: stdCamera.hpp:2007
std::string m_nextMode
The mode to be set by the next reconfiguration.
Definition: stdCamera.hpp:345
pcf::IndiProperty m_indiP_tempstat
Definition: stdCamera.hpp:271
int m_default_bin_x
Power-on ROI x binning.
Definition: stdCamera.hpp:399
int m_default_w
Power-on ROI width.
Definition: stdCamera.hpp:397
int setTempControl(const mx::meta::trueFalseT< true > &t)
Interface to setTempControl when the derivedT has temperature control.
Definition: stdCamera.hpp:1796
int newCallBack_roi_h(const pcf::IndiProperty &ipRecv)
Callback to process a NEW roi_h request.
Definition: stdCamera.hpp:2324
int recordCamera(bool force=false)
Definition: stdCamera.hpp:2898
bool m_cropMode
Status of crop mode ROIs, if enabled for this camera.
Definition: stdCamera.hpp:439
float m_maxExpTime
The maximum exposure time, used for INDI attributes.
Definition: stdCamera.hpp:309
float m_stepFPS
The FPS step size, used for INDI attributes.
Definition: stdCamera.hpp:317
int newCallBack_mode(const pcf::IndiProperty &ipRecv)
Callback to process a NEW mode request.
Definition: stdCamera.hpp:2135
int m_default_h
Power-on ROI height.
Definition: stdCamera.hpp:398
pcf::IndiProperty m_indiP_roi_last
Property used to trigger setting the last ROI.
Definition: stdCamera.hpp:430
pcf::IndiProperty m_indiP_temp
Definition: stdCamera.hpp:269
float m_expTimeSet
The exposure time, in seconds, as set by user.
Definition: stdCamera.hpp:313
pcf::IndiProperty m_indiP_roi_h
Property used to set the ROI height.
Definition: stdCamera.hpp:417
void setupConfig(mx::app::appConfigurator &config)
Setup the configuration system.
Definition: stdCamera.hpp:980
int m_full_h
The full ROI height.
Definition: stdCamera.hpp:405
pcf::IndiProperty m_indiP_synchro
Definition: stdCamera.hpp:335
int m_full_bin_y
The y-binning in the full ROI.
Definition: stdCamera.hpp:407
int checkNextROI(const mx::meta::trueFalseT< true > &t)
Interface to checkNextROI when the derivedT uses ROIs.
Definition: stdCamera.hpp:2393
int setVShiftSpeed(const mx::meta::trueFalseT< true > &t)
Interface to setVShiftSpeed when the derivedT has vshift speed control.
Definition: stdCamera.hpp:1905
float m_full_y
The full ROI center y coordinate.
Definition: stdCamera.hpp:403
static int st_newCallBack_stdCamera(void *app, const pcf::IndiProperty &ipRecv)
The static callback function to be registered for stdCamera properties.
Definition: stdCamera.hpp:1694
float m_maxFPS
The maximum FPS, used for INDI attributes.
Definition: stdCamera.hpp:316
std::string m_readoutSpeedName
The current readout speed name.
Definition: stdCamera.hpp:282
float m_ccdTempSetpt
The desired temperature, in C.
Definition: stdCamera.hpp:260
bool m_tempControlStatus
Whether or not temperature control is active.
Definition: stdCamera.hpp:262
pcf::IndiProperty m_indiP_fps
Definition: stdCamera.hpp:324
int newCallBack_roi_last(const pcf::IndiProperty &ipRecv)
Callback to process a NEW roi_last request.
Definition: stdCamera.hpp:2602
pcf::IndiProperty m_indiP_roi_loadlast
Property used to trigger loading the last ROI as the target.
Definition: stdCamera.hpp:429
pcf::IndiProperty m_indiP_roi_w
Property used to set the ROI width.
Definition: stdCamera.hpp:416
int newCallBack_roi_set(const pcf::IndiProperty &ipRecv)
Callback to process a NEW roi_set request.
Definition: stdCamera.hpp:2448
pcf::IndiProperty m_indiP_roi_default
Property used to trigger setting the default and startup ROI.
Definition: stdCamera.hpp:431
int newCallBack_stdCamera(const pcf::IndiProperty &ipRecv)
The callback function for stdCamera properties.
Definition: stdCamera.hpp:1703
std::string m_modeName
The current mode name.
Definition: stdCamera.hpp:343
pcf::IndiProperty m_indiP_reconfig
Request switch which forces the framegrabber to go through the reconfigure process.
Definition: stdCamera.hpp:349
int setSynchro(const mx::meta::trueFalseT< true > &t)
Interface to setSynchro when the derivedT has synchronization.
Definition: stdCamera.hpp:2091
pcf::IndiProperty m_indiP_roi_bin_x
Property used to set the ROI x binning.
Definition: stdCamera.hpp:418
int newCallBack_roi_loadlast(const pcf::IndiProperty &ipRecv)
Callback to process a NEW roi_loadlast request.
Definition: stdCamera.hpp:2575
pcf::IndiProperty m_indiP_readoutSpeed
Definition: stdCamera.hpp:298
int setEMGain(const mx::meta::trueFalseT< true > &t)
Interface to setEMGain when the derivedT has EM Gain.
Definition: stdCamera.hpp:1965
int newCallBack_vShiftSpeed(const pcf::IndiProperty &ipRecv)
Callback to process a NEW vshift speed request.
Definition: stdCamera.hpp:1919
std::string m_startupMode
The camera mode to load during first init after a power-on.
Definition: stdCamera.hpp:241
pcf::IndiProperty m_indiP_roi_check
Property used to trigger checking the target ROI.
Definition: stdCamera.hpp:423
pcf::IndiProperty m_indiP_vShiftSpeed
Definition: stdCamera.hpp:299
int newCallBack_roi_check(const pcf::IndiProperty &ipRecv)
Callback to process a NEW roi_check request.
Definition: stdCamera.hpp:2407
int newCallBack_roi_x(const pcf::IndiProperty &ipRecv)
Callback to process a NEW roi_x request.
Definition: stdCamera.hpp:2255
float m_full_x
The full ROI center x coordinate.
Definition: stdCamera.hpp:402
float m_startupTemp
The temperature to set after a power-on. Set to <= -999 to not use [default].
Definition: stdCamera.hpp:243
int appLogic()
Application logic.
Definition: stdCamera.hpp:1484
int m_full_currbin_h
The current-binning full ROI height.
Definition: stdCamera.hpp:412
pcf::IndiProperty m_indiP_exptime
Definition: stdCamera.hpp:322
int newCallBack_shutter(const pcf::IndiProperty &ipRecv)
Callback to process a NEW shutter request.
Definition: stdCamera.hpp:2683
bool m_synchro
Status of synchronization, true is on, false is off.
Definition: stdCamera.hpp:333
std::string m_vShiftSpeedName
The current vshift speed name.
Definition: stdCamera.hpp:288
int newCallBack_roi_full(const pcf::IndiProperty &ipRecv)
Callback to process a NEW roi_full request.
Definition: stdCamera.hpp:2477
int setCropMode(const mx::meta::trueFalseT< true > &t)
Interface to setCropMode when the derivedT has crop mode.
Definition: stdCamera.hpp:2210
pcf::IndiProperty m_indiP_emGain
Definition: stdCamera.hpp:301
float m_ccdTemp
The current temperature, in C.
Definition: stdCamera.hpp:258
int updateINDI()
Update the INDI properties for this device controller.
Definition: stdCamera.hpp:2739
std::vector< std::string > m_vShiftSpeedNames
Definition: stdCamera.hpp:285
int newCallBack_fps(const pcf::IndiProperty &ipRecv)
Callback to process a NEW fps request.
Definition: stdCamera.hpp:2063
std::string m_defaultVShiftSpeed
The default readout speed of the camera.
Definition: stdCamera.hpp:246
int newCallBack_roi_y(const pcf::IndiProperty &ipRecv)
Callback to process a NEW roi_y request.
Definition: stdCamera.hpp:2278
pcf::IndiProperty m_indiP_tempcont
Definition: stdCamera.hpp:270
bool m_tempControlOnTarget
Whether or not the temperature control system is on its target temperature.
Definition: stdCamera.hpp:265
int createVShiftSpeed(const mx::meta::trueFalseT< true > &t)
Definition: stdCamera.hpp:1095
cameraConfigMap m_cameraModes
Map holding the possible camera mode configurations.
Definition: stdCamera.hpp:239
float m_stepExpTime
The maximum exposure time stepsize, used for INDI attributes.
Definition: stdCamera.hpp:310
void loadConfig(mx::app::appConfigurator &config)
load the configuration system results
Definition: stdCamera.hpp:1019
int whilePowerOff()
Actions while powered off.
Definition: stdCamera.hpp:1655
int setFPS(const mx::meta::trueFalseT< true > &t)
Interface to setFPS when the derivedT uses FPS controls.
Definition: stdCamera.hpp:2049
int newCallBack_reconfigure(const pcf::IndiProperty &ipRecv)
Callback to process a NEW reconfigure request.
Definition: stdCamera.hpp:2187
int newCallBack_emgain(const pcf::IndiProperty &ipRecv)
Callback to process a NEW EM gain request.
Definition: stdCamera.hpp:1979
float m_full_currbin_y
The current-binning full ROI center y coordinate.
Definition: stdCamera.hpp:410
int appStartup()
Startup function.
Definition: stdCamera.hpp:1120
int newCallBack_roi_bin_x(const pcf::IndiProperty &ipRecv)
Callback to process a NEW bin_x request.
Definition: stdCamera.hpp:2347
std::vector< std::string > m_vShiftSpeedNameLabels
Definition: stdCamera.hpp:286
int setTempSetPt(const mx::meta::trueFalseT< true > &t)
Interface to setTempSetPt when the derivedT has temperature control.
Definition: stdCamera.hpp:1752
pcf::IndiProperty m_indiP_roi_full
Property used to trigger setting the full ROI.
Definition: stdCamera.hpp:427
int newCallBack_synchro(const pcf::IndiProperty &ipRecv)
Callback to process a NEW synchro request.
Definition: stdCamera.hpp:2105
int newCallBack_roi_default(const pcf::IndiProperty &ipRecv)
Callback to process a NEW roi_default request.
Definition: stdCamera.hpp:2630
pcf::IndiProperty m_indiP_roi_set
Property used to trigger setting the ROI.
Definition: stdCamera.hpp:425
int appShutdown()
Application shutdown.
Definition: stdCamera.hpp:1687
pcf::IndiProperty m_indiP_shutter
Property used to control the shutter, a switch.
Definition: stdCamera.hpp:453
int newCallBack_roi_w(const pcf::IndiProperty &ipRecv)
Callback to process a NEW roi_w request.
Definition: stdCamera.hpp:2301
pcf::IndiProperty m_indiP_stateString
Definition: stdCamera.hpp:461
pcf::IndiProperty m_indiP_mode
Property used to report the current mode.
Definition: stdCamera.hpp:347
pcf::IndiProperty m_indiP_cropMode
Property used to toggle crop mode on and off.
Definition: stdCamera.hpp:442
float m_default_y
Power-on ROI center y coordinate.
Definition: stdCamera.hpp:396
int setNextROI(const mx::meta::trueFalseT< true > &t)
Interface to setNextROI when the derivedT uses ROIs.
Definition: stdCamera.hpp:2434
pcf::IndiProperty m_indiP_fullROI
Property used to preset the full ROI dimensions.
Definition: stdCamera.hpp:421
bool stateStringValid(const mx::meta::trueFalseT< true > &t)
Interface to stateStringValid when the derivedT provides it.
Definition: stdCamera.hpp:2725
float m_fps
The current FPS.
Definition: stdCamera.hpp:319
std::string stateString(const mx::meta::trueFalseT< true > &t)
Interface to stateString when the derivedT provides it.
Definition: stdCamera.hpp:2711
pcf::IndiProperty m_indiP_roi_bin_y
Property used to set the ROI y binning.
Definition: stdCamera.hpp:419
pcf::IndiProperty m_indiP_roi_x
Property used to set the ROI x center coordinate.
Definition: stdCamera.hpp:414
int newCallBack_roi_fullbin(const pcf::IndiProperty &ipRecv)
Callback to process a NEW roi_fullbin request.
Definition: stdCamera.hpp:2511
int newCallBack_temp_controller(const pcf::IndiProperty &ipRecv)
Callback to process a NEW CCD temp control request.
Definition: stdCamera.hpp:1810
int newCallBack_exptime(const pcf::IndiProperty &ipRecv)
Callback to process a NEW exposure time request.
Definition: stdCamera.hpp:2021
int setReadoutSpeed(const mx::meta::trueFalseT< true > &t)
Interface to setReadoutSpeed when the derivedT has readout speed control.
Definition: stdCamera.hpp:1845
int m_default_bin_y
Power-on ROI y binning.
Definition: stdCamera.hpp:400
bool m_tempControlStatusSet
Desired state of temperature control.
Definition: stdCamera.hpp:263
float m_minFPS
The minimum FPS, used for INDI attributes.
Definition: stdCamera.hpp:315
int onPowerOff()
Actions on power off.
Definition: stdCamera.hpp:1592
std::string m_readoutSpeedNameSet
The user requested readout speed name, to be set by derived()
Definition: stdCamera.hpp:283
~stdCamera() noexcept
Destructor, destroys the PdvDev structure.
Definition: stdCamera.hpp:972
@ OPERATING
The device is operating, other than homing.
Definition: stateCodes.hpp:50
@ READY
The device is ready for operation, but is not operating.
Definition: stateCodes.hpp:51
@ NOTCONNECTED
The application is not connected to the device or service.
Definition: stateCodes.hpp:44
@ POWERON
The device power is on.
Definition: stateCodes.hpp:43
#define INDI_IDLE
Definition: indiUtils.hpp:28
#define INDI_BUSY
Definition: indiUtils.hpp:30
#define INDI_OK
Definition: indiUtils.hpp:29
std::unordered_map< std::string, cameraConfig > cameraConfigMap
Definition: stdCamera.hpp:48
int loadCameraConfig(cameraConfigMap &ccmap, mx::app::appConfigurator &config)
Load the camera configurations contained in the app configuration into a map.
Definition: stdCamera.cpp:18
std::string m_serialCommand
The command to send to the camera to place it in this mode.
Definition: stdCamera.hpp:34
std::string m_configFile
The file to use for this mode, e.g. an EDT configuration file.
Definition: stdCamera.hpp:33
A camera configuration.
Definition: stdCamera.hpp:32
void updateIfChanged(pcf::IndiProperty &p, const std::string &el, const T &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:95
void updateSelectionSwitchIfChanged(pcf::IndiProperty &p, const std::string &el, indiDriverT *indiDriver, pcf::IndiProperty::PropertyStateType newState=pcf::IndiProperty::Ok)
Update the values of a one-of-many INDI switch vector, but only if it has changed.
Definition: indiUtils.hpp:243
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
Definition: dm.hpp:24
constexpr static logPrioT LOG_CRITICAL
The process can not continue and will shut down (fatal)
Definition: logPriority.hpp:37
constexpr static logPrioT LOG_ERROR
An error has occured which the software will attempt to correct.
Definition: logPriority.hpp:40
constexpr static logPrioT LOG_WARNING
A condition has occurred which may become an error, but the process continues.
Definition: logPriority.hpp:43
#define CAMCTRL_E_NOCONFIGS
Definition: stdCamera.hpp:26