API
ocam2KCtrl.hpp
Go to the documentation of this file.
1 /** \file ocam2KCtrl.hpp
2  * \brief The MagAO-X OCAM2K EMCCD camera controller.
3  *
4  * \author Jared R. Males (jaredmales@gmail.com)
5  *
6  * \ingroup ocam2KCtrl_files
7  */
8 
9 #ifndef ocam2KCtrl_hpp
10 #define ocam2KCtrl_hpp
11 
12 
13 #include <edtinc.h>
14 
15 
16 
17 #include "../../libMagAOX/libMagAOX.hpp" //Note this is included on command line to trigger pch
18 #include "../../magaox_git_version.h"
19 
20 typedef MagAOX::app::MagAOXApp<true> MagAOXAppT; //This needs to be before pdvUtils.hpp for logging to work.
21 
22 #include "fli/ocam2_sdk.h"
23 #include "ocamUtils.hpp"
24 
25 namespace MagAOX
26 {
27 namespace app
28 {
29 
30 /** \defgroup ocam2KCtrl OCAM2K EMCCD Camera
31  * \brief Control of the OCAM2K EMCCD Camera.
32  *
33  * <a href="../handbook/operating/software/apps/ocam2KCtrl.html">Application Documentation</a>
34  *
35  * \ingroup apps
36  *
37  */
38 
39 /** \defgroup ocam2KCtrl_files OCAM2K EMCCD Camera Files
40  * \ingroup ocam2KCtrl
41  */
42 
43 /** MagAO-X application to control the OCAM 2K EMCCD
44  *
45  * \ingroup ocam2KCtrl
46  *
47  */
48 class ocam2KCtrl : public MagAOXApp<>, public dev::stdCamera<ocam2KCtrl>, public dev::edtCamera<ocam2KCtrl>, public dev::frameGrabber<ocam2KCtrl>,
49  public dev::dssShutter<ocam2KCtrl>, public dev::telemeter<ocam2KCtrl>
50 {
51  friend class dev::stdCamera<ocam2KCtrl>;
52  friend class dev::edtCamera<ocam2KCtrl>;
53  friend class dev::frameGrabber<ocam2KCtrl>;
54  friend class dev::dssShutter<ocam2KCtrl>;
55  friend class dev::telemeter<ocam2KCtrl>;
56 
58 
59 public:
60  /** \name app::dev Configurations
61  *@{
62  */
63  static constexpr bool c_stdCamera_tempControl = true; ///< app::dev config to tell stdCamera to expose temperature controls
64 
65  static constexpr bool c_stdCamera_temp = true; ///< app::dev config to tell stdCamera to expose temperature (ignored since tempControl==true)
66 
67  static constexpr bool c_stdCamera_readoutSpeed = false; ///< app::dev config to tell stdCamera not to expose readout speed controls
68 
69  static constexpr bool c_stdCamera_vShiftSpeed = false; ///< app:dev config to tell stdCamera not to expose vertical shift speed control
70 
71  static constexpr bool c_stdCamera_emGain = true; ///< app::dev config to tell stdCamera to expose EM gain controls
72 
73  static constexpr bool c_stdCamera_exptimeCtrl = false; ///< app::dev config to tell stdCamera not to expose exposure time controls
74 
75  static constexpr bool c_stdCamera_fpsCtrl = true; ///< app::dev config to tell stdCamera to expose FPS controls
76 
77  static constexpr bool c_stdCamera_fps = true; ///< app::dev config to tell stdCamera not to expose FPS status (ignored since fpsCtrl==true)
78 
79  static constexpr bool c_stdCamera_synchro = true; ///< app::dev config to tell stdCamera to expose synchro mode controls
80 
81  static constexpr bool c_stdCamera_usesModes = true; ///< app:dev config to tell stdCamera not to expose mode controls
82 
83  static constexpr bool c_stdCamera_usesROI = false; ///< app:dev config to tell stdCamera to expose ROI controls
84 
85  static constexpr bool c_stdCamera_cropMode = false; ///< app:dev config to tell stdCamera to expose Crop Mode controls
86 
87  static constexpr bool c_stdCamera_hasShutter = true; ///< app:dev config to tell stdCamera to expose shutter controls
88 
89  static constexpr bool c_stdCamera_usesStateString = true; ///< app::dev confg to tell stdCamera to expose the state string property
90 
91  static constexpr bool c_edtCamera_relativeConfigPath = true; ///< app::dev config to tell edtCamera to use relative path to camera config file
92 
93  static constexpr bool c_frameGrabber_flippable = false; ///< app:dev config to tell framegrabber these images can not be flipped
94 
95  ///@}
96 protected:
97 
98  /** \name configurable parameters
99  *@{
100  */
101 
102  //Camera:
103 
104  std::string m_ocamDescrambleFile; ///< Path the OCAM 2K pixel descrambling file, relative to MagAO-X config directory.
105 
106 
107 
108  ///@}
109 
110  ocam2_id m_ocam2_id {0}; ///< OCAM SDK id.
111 
112  long m_currImageNumber {-1}; ///< The current image number, retrieved from the image itself.
113 
114  long m_lastImageNumber {-1}; ///< The last image number, saved from the last loop through.
115 
116  bool m_protectionReset {false}; ///< Flag indicating that protection has been reset at least once.
117 
118  unsigned m_protectionResetConfirmed {0}; ///< Counter indicating the number of times that the protection reset has been requested within 10 seconds, for confirmation.
119 
120  double m_protectionResetReqTime {0}; ///< The time at which protection reset was requested. You have 10 seconds to confirm.
121 
122  bool m_poweredOn {false};
123 
124  ocamTemps m_temps; ///< Structure holding the last temperature measurement.
125 
126  unsigned m_digitalBinX {1};
127 
128  unsigned m_digitalBinY {1};
129 
130  bool m_digitalBin {false};
131 
132  mx::improc::eigenImage<int16_t> m_digitalBinWork;
133 
134  std::string m_syncDevice {"fxngensync"};
135  std::string m_syncFreqProp {"C1freq"};
136 
137  float m_syncFreq {0};
138 
139 public:
140 
141  ///Default c'tor
142  ocam2KCtrl();
143 
144  ///Destructor
145  ~ocam2KCtrl() noexcept;
146 
147  /// Setup the configuration system (called by MagAOXApp::setup())
148  virtual void setupConfig();
149 
150  /// load the configuration system results (called by MagAOXApp::setup())
151  virtual void loadConfig();
152 
153  /// Startup functions
154  /** Sets up the INDI vars, and the f.g. thread.
155  *
156  */
157  virtual int appStartup();
158 
159  /// Implementation of the FSM for the OCAM 2K.
160  virtual int appLogic();
161 
162  /// Implementation of the on-power-off FSM logic
163  virtual int onPowerOff();
164 
165  /// Implementation of the while-powered-off FSM
166  virtual int whilePowerOff();
167 
168  /// Do any needed shutdown tasks.
169  virtual int appShutdown();
170 
171  /// Get the current device temperatures
172  /**
173  * \returns 0 on success
174  * \returns -1 on error
175  */
176  int getTemps();
177 
178  /// Get the current frame rate.
179  /**
180  * \returns 0 on success
181  * \returns -1 on error
182  */
183  int getFPS();
184 
185  /** \name stdCamera Interface
186  *
187  * @{
188  */
189 
190  /// Set defaults for a power on state.
191  /**
192  * \returns 0 on success
193  * \returns -1 on error
194  */
195  int powerOnDefaults();
196 
197  /// Turn temperature control on or off.
198  /** Sets temperature control on or off based on the current value of m_tempControlStatus
199  * \returns 0 on success
200  * \returns -1 on error
201  */
202  int setTempControl();
203 
204  /// Set the CCD temperature setpoint [stdCamera interface].
205  /** Sets the temperature to m_ccdTempSetpt.
206  * \returns 0 on success
207  * \returns -1 on error
208  */
209  int setTempSetPt();
210 
211  /// Set the frame rate. [stdCamera interface]
212  /** Sets the frame rate to m_fpsSet.
213  *
214  * \returns 0 on success
215  * \returns -1 on error
216  */
217  int setFPS();
218 
219  /// Set the synchro state. [stdCamera interface]
220  /** Sets the synchro state to m_synchroSet.
221  *
222  * \returns 0 on success
223  * \returns -1 on error
224  */
225  int setSynchro();
226 
227  /// Required by stdCamera, but this does not do anything for this camera [stdCamera interface]
228  /**
229  * \returns 0 always
230  */
231  int setExpTime();
232 
233  /// Required by stdCamera, but this does not do anything for this camera [stdCamera interface]
234  /**
235  * \returns 0 always
236  */
237  int setNextROI();
238 
239  /// Sets the shutter state, via call to dssShutter::setShutterState(int) [stdCamera interface]
240  /**
241  * \returns 0 always
242  */
243  int setShutter(int sh);
244 
245  std::string stateString();
246 
247  bool stateStringValid();
248 
249  ///@}
250 
251  /// Reset the EM Protection
252  /**
253  * \returns 0 on success
254  * \returns -1 on error
255  */
256  int resetEMProtection();
257 
258  /// Get the current EM Gain.
259  /**
260  * \returns 0 on success
261  * \returns -1 on error
262  */
263  int getEMGain();
264 
265  /// Set the EM gain.
266  /** Sets it to the value of stdCamera::m_emGainSet
267  *
268  * \returns 0 on success
269  * \returns -1 on error
270  */
271  int setEMGain();
272 
273  /// Implementation of the framegrabber configureAcquisition interface
274  /** Sends the mode command over serial, sets the FPS, and initializes the OCAM SDK.
275  *
276  * \returns 0 on success
277  * \returns -1 on error
278  */
279  int configureAcquisition();
280 
281  /// Implementation of the frameGrabber fps interface
282  /** Just returns the value of m_fps
283  */
284  float fps();
285 
286  /// Implementation of the framegrabber startAcquisition interface
287  /** Initializes m_lastImageNumber, and calls edtCamera::pdvStartAcquisition
288  *
289  * \returns 0 on success
290  * \returns -1 on error
291  */
292  int startAcquisition();
293 
294  /// Implementation of the framegrabber acquireAndCheckValid interface
295  /** Calls edtCamera::pdvAcquire, then analyzes the OCAM generated framenumber for skips and corruption.
296  *
297  * \returns 0 on success
298  * \returns -1 on error
299  */
300  int acquireAndCheckValid();
301 
302  /// Implementation of the framegrabber loadImageIntoStream interface
303  /** Conducts the OCAM descramble.
304  *
305  * \returns 0 on success
306  * \returns -1 on error
307  */
308  int loadImageIntoStream( void * dest /**< [in] */);
309 
310  /// Implementation of the framegrabber reconfig interface
311  /** Locks the INDI mutex and calls edtCamera::pdvReconfig.
312  * \returns 0 on success
313  * \returns -1 on error
314  */
315  int reconfig();
316 
317 
318  //INDI:
319 protected:
320  //declare our properties
321  pcf::IndiProperty m_indiP_temps;
322  pcf::IndiProperty m_indiP_emProt;
323  pcf::IndiProperty m_indiP_emProtReset;
324 
325  pcf::IndiProperty m_indiP_syncFreq;
326 
327 public:
329 
331 
332  /** \name Telemeter Interface
333  *
334  * @{
335  */
336  int checkRecordTimes();
337 
338  int recordTelem( const ocam_temps * );
339 
340  int recordTelem( const telem_stdcam * );
341 
342  int recordTelem( const telem_fgtimings * );
343 
344  int recordTemps(bool force = false);
345 
346  ///@}
347 };
348 
349 inline
350 ocam2KCtrl::ocam2KCtrl() : MagAOXApp(MAGAOX_CURRENT_SHA1, MAGAOX_REPO_MODIFIED)
351 {
352  //--- MagAOXApp Power Mgt. ---
353  m_powerMgtEnabled = true;
354  m_powerOnWait = 10;
355 
356  //--- stdCamera ---
357  m_startupTemp = 20;
358 
359  m_maxEMGain = 600;
360 
361  return;
362 }
363 
364 inline
366 {
367  return;
368 }
369 
370 inline
372 {
374 
376 
377  config.add("camera.ocamDescrambleFile", "", "camera.ocamDescrambleFile", argType::Required, "camera", "ocamDescrambleFile", false, "string", "The path of the OCAM descramble file, relative to MagAOX/config.");
378 
380 
382 
384 }
385 
386 
387 inline
389 {
392 
393  config(m_ocamDescrambleFile, "camera.ocamDescrambleFile");
394 
395  if(m_maxEMGain < 1)
396  {
397  m_maxEMGain = 1;
398  log<text_log>("maxEMGain set to 1");
399  }
400 
401  if(m_maxEMGain > 600)
402  {
403  m_maxEMGain = 600;
404  log<text_log>("maxEMGain set to 600");
405  }
406 
410 }
411 
412 inline
414 {
415  REG_INDI_NEWPROP_NOCB(m_indiP_temps, "temps", pcf::IndiProperty::Number);
416  m_indiP_temps.add (pcf::IndiElement("cpu"));
417  m_indiP_temps["cpu"].set(0);
418  m_indiP_temps.add (pcf::IndiElement("power"));
419  m_indiP_temps["power"].set(0);
420  m_indiP_temps.add (pcf::IndiElement("bias"));
421  m_indiP_temps["bias"].set(0);
422  m_indiP_temps.add (pcf::IndiElement("water"));
423  m_indiP_temps["water"].set(0);
424  m_indiP_temps.add (pcf::IndiElement("left"));
425  m_indiP_temps["left"].set(0);
426  m_indiP_temps.add (pcf::IndiElement("right"));
427  m_indiP_temps["right"].set(0);
428  m_indiP_temps.add (pcf::IndiElement("cooling"));
429  m_indiP_temps["cooling"].set(0);
430 
431  REG_INDI_NEWPROP_NOCB(m_indiP_emProt, "emProtection", pcf::IndiProperty::Text);
432  m_indiP_emProt.add(pcf::IndiElement("status"));
433  m_indiP_emProt["status"].set("UNKNOWN");
434  m_indiP_emProt.setState(INDI_IDLE);
435 
436  createStandardIndiRequestSw( m_indiP_emProtReset, "emProtectionReset", "Reset", "EM Protection");
438 
440 
442  {
443  return log<software_critical,-1>({__FILE__,__LINE__});
444  }
445 
447  {
448  return log<software_critical,-1>({__FILE__,__LINE__});
449  }
450 
452  {
453  return log<software_critical,-1>({__FILE__,__LINE__});
454  }
455 
457  {
458  return log<software_critical,-1>({__FILE__,__LINE__});
459  }
460 
463  {
464  return log<software_error,-1>({__FILE__,__LINE__});
465  }
466 
467  return 0;
468 
469 }
470 
471 
472 
473 inline
475 {
476 
477  //and run stdCamera's appLogic
479  {
480  return log<software_error, -1>({__FILE__, __LINE__});
481  }
482 
483  //and run edtCamera's appLogic
485  {
486  return log<software_error, -1>({__FILE__, __LINE__});
487  }
488 
489  //first run frameGrabber's appLogic to see if the f.g. thread has exited.
491  {
492  return log<software_error, -1>({__FILE__, __LINE__});
493  }
494 
495  //and run dssShutter's appLogic
497  {
498  return log<software_error, -1>({__FILE__, __LINE__});
499  }
500 
501  if( state() == stateCodes::POWERON) return 0;
502 
504  {
506 
507  std::string response;
508 
509  //Might have gotten here because of a power off.
510  if(MagAOXAppT::m_powerState == 0) return 0;
511 
512  int ret = pdvSerialWriteRead( response, "fps"); //m_pdv, "fps", m_readTimeout);
513  if( ret == 0)
514  {
516  }
517  else
518  {
519  sleep(1);
520  return 0;
521  }
522  }
523 
524  if( state() == stateCodes::CONNECTED )
525  {
526  //Get a lock
527  std::unique_lock<std::mutex> lock(m_indiMutex);
528 
529  if( getFPS() == 0 )
530  {
531  if(m_fpsSet == 0) state(stateCodes::READY);
533 
534  if(m_poweredOn && m_ccdTempSetpt > -999)
535  {
536  m_poweredOn = false;
537  if(setTempSetPt() < 0)
538  {
539  if(powerState() != 1 || powerStateTarget() != 1) return 0;
540  return log<software_error,0>({__FILE__,__LINE__});
541  }
542  }
543 
544  //We always have to set synchro on connecting, b/c otherwise we don't know the state.
545  m_synchroSet = false;
546  if( setSynchro() != 0 )
547  {
548  log<software_error>({__FILE__, __LINE__, "error from setSynchro on CONNECT"});
549  }
550  }
551  else
552  {
553  if(powerState() != 1 || powerStateTarget() != 1) return 0;
555  return log<software_error,0>({__FILE__,__LINE__});
556  }
557  }
558 
560  {
561  //Get a lock if we can
562  std::unique_lock<std::mutex> lock(m_indiMutex, std::try_to_lock);
563 
564  //but don't wait for it, just go back around.
565  if(!lock.owns_lock()) return 0;
566 
567  if(getTemps() < 0)
568  {
569  if(powerState() != 1 || powerStateTarget() != 1) return 0;
572  return 0;
573  }
574 
575  if(getFPS() < 0)
576  {
577  if(powerState() != 1 || powerStateTarget() != 1) return 0;
578 
580  return 0;
581  }
582 
584  {
585  if( mx::sys::get_curr_time() - m_protectionResetReqTime > 10.0)
586  {
588  updateIfChanged(m_indiP_emProt, "status", std::string("UNCONFIRMED"));
589  log<text_log>("protection reset request not confirmed", logPrio::LOG_NOTICE);
590  }
591  }
592 
593  if(getEMGain () < 0)
594  {
595  if(MagAOXAppT::m_powerState == 0) return 0;
596 
598  return 0;
599  }
600 
602  {
603  log<software_error>({__FILE__, __LINE__});
605  return 0;
606  }
607 
609  {
610  log<software_error>({__FILE__, __LINE__});
612  return 0;
613  }
614 
616  {
617  log<software_error>({__FILE__, __LINE__});
619  return 0;
620  }
621 
623  {
624  log<software_error>({__FILE__, __LINE__});
625  return 0;
626  }
627 
628  }
629 
630  ///\todo Fall through check?
631 
632  return 0;
633 
634 }
635 
636 inline
638 {
639  m_powerOnCounter = 0;
640 
641  std::lock_guard<std::mutex> lock(m_indiMutex);
642 
643  updateIfChanged(m_indiP_emProt, "status", std::string("UNKNOWN"), INDI_IDLE);
644 
646 
654 
656  {
657  log<software_error>({__FILE__, __LINE__});
658  }
659 
661  {
662  log<software_error>({__FILE__, __LINE__});
663  }
664 
666  {
667  log<software_error>({__FILE__, __LINE__});
668  }
669 
671  {
672  log<software_error>({__FILE__, __LINE__});
673  }
674 
675  //Setting m_poweredOn
676  m_poweredOn = true;
677 
678 
679  return 0;
680 }
681 
682 inline
684 {
685  std::lock_guard<std::mutex> lock(m_indiMutex);
686 
688  {
689  log<software_error>({__FILE__, __LINE__});
690  }
691 
693  {
694  log<software_error>({__FILE__, __LINE__});
695  }
696 
698  {
699  log<software_error>({__FILE__, __LINE__});
700  }
701 
702  return 0;
703 }
704 
705 inline
707 {
708  ///\todo error check these base class fxns.
709 
711 
713 
715 
717 
719 
720  return 0;
721 }
722 
723 
724 inline
726 {
727  std::string response;
728 
729  if( pdvSerialWriteRead( response, "temp") == 0)
730  {
731  ocamTemps temps;
732 
733  if(parseTemps( temps, response ) < 0)
734  {
735  if(powerState() != 1 || powerStateTarget() != 1) return -1;
736 
740  m_tempControlStatus = false;
741  m_tempControlStatusStr = "UNKNOWN";
742 
743  recordTemps();
744  recordCamera();
745  return log<software_error, -1>({__FILE__, __LINE__, "Temp. parse error"});
746  }
747 
748  m_temps = temps;
749 
750  //stdCamera temp control:
753 
754  //Detect that temperature control is off
755  if(m_temps.COOLING_POWER < 5)
756  {
757  if( m_temps.CCD - m_temps.SET > 2.99 )
758  {
759  m_tempControlStatus = false;
760  }
761  }
762  else m_tempControlStatus = true;
763 
764  if(m_tempControlStatus == true)
765  {
766  if(fabs(m_temps.CCD - m_temps.SET) < 1.0)
767  {
768  m_tempControlStatusStr = "ON TARGET";
769  m_tempControlOnTarget = true;
770  }
771  else
772  {
773  m_tempControlStatusStr = "OFF TARGET";
774  m_tempControlOnTarget = false;
775  }
776  }
777  else
778  {
779  m_tempControlStatusStr = "TEMP OFF";
780  m_tempControlOnTarget = false;
781  }
782 
783 
784  //Telemeter:
785  recordTemps();
786  recordCamera();
787 
795  return 0;
796 
797  }
798  else
799  {
800  if(powerState() != 1 || powerStateTarget() != 1) return -1;
801  return log<software_error,-1>({__FILE__, __LINE__});
802  }
803 }
804 
805 inline
807 {
808  //Camera boots up with this true in most cases.
809  m_tempControlStatusSet = false;
810  m_tempControlStatus =false;
811 
812  return 0;
813 }
814 
815 inline
817 {
818  std::string response;
819 
820  std::string command;
821 
822  std::string comStr = "temp ";
824  {
825  command = "on";
826  m_tempControlStatusSet = true;
827  m_tempControlStatus = true;
828  }
829  else
830  {
831  if( m_ccdTemp > 19) //19 is 20 with a 1 C slop
832  {
833  command = "off";
834  m_tempControlStatusSet = false;
835  m_tempControlStatus = false;
836  }
837  else
838  {
839  return log<text_log,-1>("Can not turn temp control off when not at 20 C or higher", logPrio::LOG_ERROR);
840  }
841  }
842 
843  comStr += command;
844 
845  if( pdvSerialWriteRead( response, comStr) == 0)
846  {
847  std::cerr << "response: " << response << "\n";
848  ///\todo check response
849  log<text_log,0>({"Set temperature control to " + command});
850  }
851  else
852  {
853  if(powerState() != 1 || powerStateTarget() != 1) return -1;
854  return log<software_error,-1>({__FILE__, __LINE__});
855  }
856 
858  {
859  return setTempSetPt();
860  }
861 
862  recordCamera();
863 
864  return 0;
865 }
866 
867 inline
869 {
870  std::string response;
871 
872  std::string tempStr = std::to_string( m_ccdTempSetpt );
873 
874  ///\todo make more configurable
875  if(m_ccdTempSetpt >= 30 || m_ccdTempSetpt < -50)
876  {
877  return log<text_log,-1>({"attempt to set temperature outside valid range: " + tempStr}, logPrio::LOG_ERROR);
878  }
879 
880  if( pdvSerialWriteRead( response, "temp " + tempStr) == 0)
881  {
882  std::cerr << "response: " << response << "\n";
883 
884  recordCamera();
885 
886  ///\todo check response
887  std::cerr << "temp " << tempStr << " response: " << response << "\n";
888 
889  return log<text_log,0>({"set temperature: " + tempStr});
890  }
891  else
892  {
893  if(powerState() != 1 || powerStateTarget() != 1) return -1;
894  return log<software_error,-1>({__FILE__, __LINE__});
895  }
896 
897 }
898 
899 inline
901 {
902  if(!m_synchro)
903  {
904  std::string response;
905 
906  if( pdvSerialWriteRead( response, "fps") == 0) // m_pdv, "fps", m_readTimeout) == 0)
907  {
908  float fps;
909  if(parseFPS( fps, response ) < 0)
910  {
911  if(powerState() != 1 || powerStateTarget() != 1) return -1;
912  return log<software_error, -1>({__FILE__, __LINE__, "fps parse error"});
913  }
914  m_fps = fps;
915 
916  recordCamera();
917 
918  return 0;
919 
920  }
921  else
922  {
923  return log<software_error,-1>({__FILE__, __LINE__});
924  }
925  }
926  else
927  {
928  m_fps = m_syncFreq;
929  recordCamera();
930 
931  return 0;
932  }
933 }
934 
935 inline
937 {
938  std::string fpsStr= std::to_string(m_fpsSet);
939 
940  if(!m_synchro)
941  {
942  std::string response;
943 
944  if( pdvSerialWriteRead( response, "fps " + fpsStr ) == 0)
945  {
946  ///\todo check response
947  std::cerr << "fps " << fpsStr << " response: " << response << "\n";
948  log<text_log>({"set fps: " + fpsStr});
949 
950  //We always want to reset the latency circular buffers
951  ///\todo verify that this works!!
953  m_reconfig = true;
954 
955  }
956  else
957  {
958  if(powerState() != 1 || powerStateTarget() != 1) return -1;
959  return log<software_error,-1>({__FILE__, __LINE__});
960  }
961  }
962  else
963  {
964  std::cerr << "setting: " << fpsStr << "\n";
965 
966  pcf::IndiProperty ipFreq(pcf::IndiProperty::Number);
967 
968  ipFreq.setDevice(m_syncDevice);
969  ipFreq.setName(m_syncFreqProp);
970  ipFreq.add(pcf::IndiElement("target"));
971 
972  ipFreq["target"] = fpsStr;
973 
974  sendNewProperty(ipFreq);
975  }
976 
977 
978 
979  return 0;
980 }
981 
982 inline
984 {
985  std::string response;
986 
987  //First set the actual FPS to 0 to get to max
988  std::string fpsStr= std::to_string(0);
989  if( pdvSerialWriteRead( response, "fps " + fpsStr ) == 0)
990  {
991  ///\todo check response
992  std::cerr << "fps " << fpsStr << " response: " << response << "\n";
993  log<text_log>({"set fps: " + fpsStr});
994  }
995  else
996  {
997  if(powerState() != 1 || powerStateTarget() != 1) return -1;
998  return log<software_error,-1>({__FILE__, __LINE__});
999  }
1000 
1001  //Now actually turn synchro on
1002  std::string sStr;
1003  if(m_synchroSet) sStr = "on";
1004  else sStr = "off";
1005  if( pdvSerialWriteRead( response, "synchro " + sStr ) == 0)
1006  {
1007  ///\todo check response
1008  std::cerr << "synchro " << sStr << " resonse: " << response << "\n";
1009  log<text_log>({"set synchro: " + sStr});
1010 
1012 
1013  if(m_synchro == false)
1014  {
1015  updateSwitchIfChanged(m_indiP_synchro, "toggle", pcf::IndiElement::Off, INDI_IDLE);
1016  }
1017  else
1018  {
1019  updateSwitchIfChanged(m_indiP_synchro, "toggle", pcf::IndiElement::On, INDI_OK);
1020  }
1021  }
1022  else
1023  {
1024  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1025  return log<software_error,-1>({__FILE__, __LINE__});
1026  }
1027 
1028  //Finally we set the FPS of the synchro device
1029  return setFPS();
1030 }
1031 
1032 inline
1034 {
1035  return 0;
1036 }
1037 
1038 inline
1040 {
1041  return 0;
1042 }
1043 
1044 inline
1046 {
1048 }
1049 
1050 inline
1052 {
1053  std::string ss;
1054 
1055  ss += m_modeName + "_";
1056  ss += std::to_string(m_fps) + "_";
1057  ss += std::to_string(m_emGain) + "_";
1058  ss += std::to_string(m_ccdTempSetpt);
1059 
1060  return ss;
1061 }
1062 
1063 inline
1065 {
1067  {
1068  return true;
1069  }
1070  else return false;
1071 }
1072 
1073 inline
1075 {
1076  std::string response;
1077 
1078  if( pdvSerialWriteRead( response, "protection reset") == 0)
1079  {
1080  std::cerr << "\n******************************************\n";
1081  std::cerr << "protection reset:\n";
1082  std::cerr << response << "\n";
1083  std::cerr << "\n******************************************\n";
1084  ///\todo check response.
1085 
1086  updateIfChanged(m_indiP_emProt, "status", std::string("RESET"), INDI_OK);
1087 
1088  log<text_log>("overillumination protection has been reset", logPrio::LOG_NOTICE);
1089 
1091 
1092  m_protectionReset = true;
1093 
1094  return 0;
1095 
1096  }
1097  else
1098  {
1099  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1100  return log<software_error,-1>({__FILE__, __LINE__});
1101  }
1102 }
1103 
1104 inline
1106 {
1107  std::string response;
1108 
1109  if( pdvSerialWriteRead( response, "gain") == 0)
1110  {
1111  unsigned emGain;
1112  if(parseEMGain( emGain, response ) < 0)
1113  {
1114  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1115 
1116  std::cerr << "EM Gain parse error, response: " << response << "\n";
1117  return log<software_error, -1>({__FILE__, __LINE__, "EM Gain parse error"});
1118  }
1119  m_emGain = emGain;
1120 
1121  return 0;
1122 
1123  }
1124  else
1125  {
1126  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1127  return log<software_error,-1>({__FILE__, __LINE__});
1128  }
1129 }
1130 
1131 inline
1133 {
1134  std::string response;
1135 
1136  if(m_protectionReset == false)
1137  {
1138  log<text_log>("Attempt to set EM gain before protection reset", logPrio::LOG_NOTICE);
1139  return 0;
1140  }
1141 
1142  unsigned emg = m_emGainSet; //a float
1143 
1144  if(emg < 1 || emg > m_maxEMGain)
1145  {
1146  log<text_log>("Attempt to set EM gain to " + std::to_string(emg) + " outside limits refused", logPrio::LOG_WARNING);
1147  return 0;
1148  }
1149 
1150  std::string emgStr= std::to_string(emg);
1151  if( pdvSerialWriteRead( response, "gain " + emgStr ) == 0) //m_pdv, "gain " + emgStr, m_readTimeout) == 0)
1152  {
1153  ///\todo check response
1154  std::cerr << "gain " << emgStr << " response: " << emgStr << "\n";
1155 
1156  log<text_log>({"set EM Gain: " + emgStr});
1157 
1158  return 0;
1159  }
1160  else
1161  {
1162  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1163  return log<software_error,-1>({__FILE__, __LINE__});
1164  }
1165 
1166 }
1167 
1168 inline
1170 {
1171  //lock mutex
1172  std::unique_lock<std::mutex> lock(m_indiMutex);
1173 
1174  //Send command to camera to place it in the correct mode
1175  std::string response;
1176  if( pdvSerialWriteRead( response, m_cameraModes[m_modeName].m_serialCommand) != 0) //m_pdv, m_cameraModes[m_modeName].m_serialCommand, m_readTimeout) != 0)
1177  {
1178  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1179 
1180  log<software_error>({__FILE__, __LINE__, "Error sending command to set mode"});
1181  sleep(1);
1182  return -1;
1183  }
1184 
1185  m_currentROI.x = 119.5;
1186  m_currentROI.y = 119.5;
1187  m_currentROI.w = 240;
1188  m_currentROI.h = 240;
1189  m_currentROI.bin_x = m_cameraModes[m_modeName].m_binningX;
1190  m_currentROI.bin_y = m_cameraModes[m_modeName].m_binningY;
1191 
1192  m_digitalBinX = m_cameraModes[m_modeName].m_digitalBinX;
1193  m_digitalBinY = m_cameraModes[m_modeName].m_digitalBinY;
1194 
1195  if(m_digitalBinX > 1)
1196  {
1197  m_digitalBin = true;
1198  std::cerr << "digital binning!\n";
1199  }
1200  else
1201  {
1202  m_digitalBin = false;
1203  }
1204 
1205  recordCamera();
1206 
1207  ///\todo check response of pdvSerialWriteRead
1208  log<text_log>("camera configured with: " +m_cameraModes[m_modeName].m_serialCommand);
1209 
1210  if(m_fpsSet > 0) setFPS();
1211 
1212  log<text_log>("Send command to set mode: " + m_cameraModes[m_modeName].m_serialCommand);
1213  log<text_log>("Response was: " + response);
1214 
1215  if(setSynchro() < 0)
1216  {
1217  log<software_error>({__FILE__, __LINE__, "Error setting synchro during configureAcquisition"});
1218  }
1219 
1220  /* Initialize the OCAM2 SDK
1221  */
1222 
1223  if(m_ocam2_id > 0)
1224  {
1226  }
1227  ocam2_rc rc;
1228  ocam2_mode mode;
1229 
1230  int OCAM_SZw;
1231  int OCAM_SZh;
1232  if(m_raw_height == 121)
1233  {
1234  mode = OCAM2_NORMAL;
1235  OCAM_SZw = 240;
1236  OCAM_SZh = 240;
1237  }
1238  else if (m_raw_height == 62)
1239  {
1240  mode = OCAM2_BINNING;
1241  OCAM_SZw = 120;
1242  OCAM_SZh = 120;
1243  }
1244  else if (m_raw_height == 41)
1245  {
1246  mode = OCAM2_BINNING1x3;
1247  OCAM_SZw = 240;
1248  OCAM_SZh = 80;
1249  }
1250  else if (m_raw_height == 31)
1251  {
1252  mode = OCAM2_BINNING1x4;
1253  OCAM_SZw = 240;
1254  OCAM_SZh = 60;
1255  }
1256  else
1257  {
1258  log<text_log>("Unrecognized OCAM2 mode.", logPrio::LOG_ERROR);
1259  return -1;
1260  }
1261 
1262  std::string ocamDescrambleFile = m_configDir + "/" + m_ocamDescrambleFile;
1263 
1264  std::cerr << "ocamDescrambleFile: " << ocamDescrambleFile << std::endl;
1265 
1266  rc=ocam2_init(mode, ocamDescrambleFile.c_str(), &m_ocam2_id);
1267 
1268  if (rc != OCAM2_OK)
1269  {
1270  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1271  log<text_log>("ocam2_init error. Failed to initialize OCAM SDK with descramble file: " + ocamDescrambleFile, logPrio::LOG_ERROR);
1272  return -1;
1273  }
1274 
1275 
1276  log<text_log>("OCAM2K initialized. id: " + std::to_string(m_ocam2_id));
1277 
1278  log<text_log>(std::string("OCAM2K mode is:") + ocam2_modeStr(ocam2_getMode(m_ocam2_id)));
1279 
1280 
1281 
1282 
1283  if(m_digitalBin)
1284  {
1285  std::cerr << "and digital binning!\n";
1286  m_digitalBinWork.resize(OCAM_SZw, OCAM_SZh);
1287 
1288  m_width = OCAM_SZw / m_digitalBinX;
1289  m_height = OCAM_SZh / m_digitalBinY;
1290  }
1291  else
1292  {
1293  m_width = OCAM_SZw;
1294  m_height = OCAM_SZh;
1295  }
1296 
1297  m_dataType = _DATATYPE_UINT16;
1298 
1300 
1301  return 0;
1302 }
1303 
1304 inline
1306 {
1307  return m_fps;
1308 }
1309 
1310 inline
1312 {
1313  m_lastImageNumber = -1;
1315 
1316 }
1317 
1318 inline
1320 {
1322 
1323  /* Removed all pdv timeout and overrun checking, since we can rely on frame number from the camera
1324  to detect missed and corrupted frames.
1325 
1326  See ef0dd24 for last version with full checks in it.
1327  */
1328 
1329  //Get the image number to see if this is valid.
1330  //This is how it is in the ocam2_sdk:
1331  unsigned currImageNumber = ((int *)m_image_p)[OCAM2_IMAGE_NB_OFFSET/4]; /* int offset */
1332  m_currImageNumber = currImageNumber;
1333 
1334  //For the first loop after a restart
1335  if( m_lastImageNumber == -1 )
1336  {
1338  }
1339 
1341  {
1342  //Detect exact condition of a wraparound on the unsigned int.
1343  // Yes, this can only happen once every 13.72 days at 3622 fps
1344  // But just in case . . .
1345  if(m_lastImageNumber != std::numeric_limits<unsigned int>::max() && m_currImageNumber != 0)
1346  {
1347  //The far more likely case is a problem...
1348 
1349  //If a reasonably small number of frames skipped, then we trust the image number
1351  {
1352  //This we handle as a non-timeout -- report how many frames were skipped
1353  long framesSkipped = m_currImageNumber - m_lastImageNumber - 1;
1354 
1355  log<text_log>("frames skipped: " + std::to_string(framesSkipped), logPrio::LOG_ERROR);
1356 
1357  m_lastImageNumber = -1;
1359  m_reconfig = 1;
1360  return 1;
1361 
1362  }
1363  else //but if it's any bigger or < 0, it's probably garbage
1364  {
1365  if(powerState() != 1 || powerStateTarget() != 1) return -1;
1366 
1367  ///\todo need frame corrupt log type
1368  log<text_log>("frame number possibly corrupt: " + std::to_string(m_currImageNumber) + " - " + std::to_string(m_lastImageNumber), logPrio::LOG_ERROR);
1369 
1371  m_reconfig = 1;
1372 
1373  //Reset the counters.
1374  m_lastImageNumber = -1;
1375  return 1;
1376 
1377  }
1378  }
1379  }
1381  return 0;
1382 }
1383 
1384 inline
1386 {
1387  unsigned currImageNumber = 0;
1388 
1389  if(!m_digitalBin)
1390  {
1391  ocam2_descramble(m_ocam2_id, &currImageNumber, reinterpret_cast<int16_t *>(dest), reinterpret_cast<int16_t *>(m_image_p));
1392  //memcpy(dest, m_image_p, 120*120*2); //This is about 10 usec faster -- but we have to descramble.
1393  }
1394  else
1395  {
1396  ocam2_descramble(m_ocam2_id, &currImageNumber, m_digitalBinWork.data(), reinterpret_cast<int16_t *>(m_image_p));
1397 
1398  mx::improc::eigenMap<int16_t> destMap( reinterpret_cast<int16_t*>(dest), m_width, m_height);
1399 
1400  if(m_digitalBinX > 1)
1401  {
1402  for(int cc = 0; cc < destMap.cols(); ++cc)
1403  {
1404  for(int rr = 0; rr < destMap.rows(); ++rr)
1405  {
1406  destMap(rr,cc) = m_digitalBinWork(rr*m_digitalBinX + 0, cc);
1407 
1408  for(unsigned b = 1; b < m_digitalBinX; ++b)
1409  {
1410  destMap(rr,cc) = m_digitalBinWork(rr*m_digitalBinX + b,cc);
1411  }
1412  }
1413  }
1414  }
1415  }
1416 
1417 
1418  return 0;
1419 }
1420 
1421 inline
1423 {
1424  //lock mutex
1425  std::unique_lock<std::mutex> lock(m_indiMutex);
1426 
1428  if(rv < 0) return rv;
1430  return 0;
1431 }
1432 
1434 {
1435  if(MagAOXAppT::m_powerState == 0) return 0;
1436 
1437  if (ipRecv.getName() != m_indiP_emProtReset.getName())
1438  {
1439  log<software_error>({__FILE__,__LINE__, "wrong INDI property received."});
1440  return -1;
1441  }
1442 
1443  if(!ipRecv.find("request"))
1444  {
1445  return 0;
1446  }
1447 
1448  if( ipRecv["request"].getSwitchState() == pcf::IndiElement::Off )
1449  {
1450  return 0;
1451  }
1452 
1453  std::unique_lock<std::mutex> lock(m_indiMutex);
1454 
1456  {
1457  updateIfChanged(m_indiP_emProt, "status", std::string("CONFIRM"), INDI_BUSY);
1458 
1460 
1461  m_protectionResetReqTime = mx::sys::get_curr_time();
1462 
1463  log<text_log>("protection reset requested", logPrio::LOG_NOTICE);
1464 
1465  return 0;
1466  }
1467 
1468 
1469  //If here, this is a confirmation.
1470  return resetEMProtection();
1471 }
1472 
1474 {
1476 
1477  if(!ipRecv.find("current"))
1478  {
1479  return -1;
1480  }
1481 
1482  m_syncFreq = ipRecv["current"].get<double>();
1483 
1484  if(m_synchro && m_syncFreq != m_fps)
1485  {
1486  recordCamera(true);
1487  m_fps = m_syncFreq;
1488 
1489  //We always want to reset the latency circular buffers
1491  m_reconfig = true;
1492  }
1493 
1494  return 0;
1495 }
1496 
1497 inline
1499 {
1501 }
1502 
1503 inline
1505 {
1506  return recordTemps(true);
1507 }
1508 
1509 inline
1511 {
1512  return recordCamera(true);
1513 }
1514 
1515 inline
1517 {
1518  return recordFGTimings(true);
1519 }
1520 
1521 inline
1522 int ocam2KCtrl::recordTemps( bool force )
1523 {
1524  static ocamTemps lastTemps;
1525 
1526  if(!(lastTemps == m_temps) || force)
1527  {
1529  lastTemps = m_temps;
1530  }
1531 
1532  return 0;
1533 }
1534 
1535 }//namespace app
1536 } //namespace MagAOX
1537 
1538 #endif
void updateIfChanged(pcf::IndiProperty &p, const std::string &el, const T &newVal, pcf::IndiProperty::PropertyStateType ipState=pcf::IndiProperty::Ok)
Update an INDI property element value if it has changed.
Definition: MagAOXApp.hpp:3120
int createStandardIndiRequestSw(pcf::IndiProperty &prop, const std::string &name, const std::string &label="", const std::string &group="")
Create a standard R/W INDI switch with a single request element.
Definition: MagAOXApp.hpp:2573
stateCodes::stateCodeT state()
Get the current state code.
Definition: MagAOXApp.hpp:2297
int registerIndiPropertyNew(pcf::IndiProperty &prop, int(*)(void *, const pcf::IndiProperty &))
Register an INDI property which is exposed for others to request a New Property for.
int powerState()
Returns the current power state.
Definition: MagAOXApp.hpp:3414
int m_powerState
Current power state, 1=On, 0=Off, -1=Unk.
Definition: MagAOXApp.hpp:1033
int powerStateTarget()
Returns the target power state.
Definition: MagAOXApp.hpp:3423
void updateSwitchIfChanged(pcf::IndiProperty &p, const std::string &el, const pcf::IndiElement::SwitchStateType &newVal, pcf::IndiProperty::PropertyStateType ipState=pcf::IndiProperty::Ok)
Update an INDI switch element value if it has changed.
Definition: MagAOXApp.hpp:3144
static int log(const typename logT::messageT &msg, logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry.
Definition: MagAOXApp.hpp:1804
std::string m_configDir
The path to configuration files for MagAOX.
Definition: MagAOXApp.hpp:85
unsigned long m_powerOnWait
Time in sec to wait for device to boot after power on.
Definition: MagAOXApp.hpp:1026
std::mutex m_indiMutex
Mutex for locking INDI communications.
Definition: MagAOXApp.hpp:545
int sendNewProperty(const pcf::IndiProperty &ipSend, const std::string &el, const T &newVal)
Send a newProperty command to another device (using the INDI Client interface)
Definition: MagAOXApp.hpp:3268
MagAO-X Uniblitz DSS Shutter interface.
Definition: dssShutter.hpp:37
int whilePowerOff()
Actions while powered off.
Definition: dssShutter.hpp:480
void loadConfig(mx::app::appConfigurator &config)
load the configuration system results
Definition: dssShutter.hpp:322
int onPowerOff()
Actions on power off.
Definition: dssShutter.hpp:474
int appShutdown()
applogic shutdown
Definition: dssShutter.hpp:437
void setupConfig(mx::app::appConfigurator &config)
Setup the configuration system.
Definition: dssShutter.hpp:304
int setShutterState(int sh)
Change shutter state.
Definition: dssShutter.hpp:486
MagAO-X EDT framegrabber interface.
Definition: edtCamera.hpp:57
u_char * m_image_p
The image data grabbed.
Definition: edtCamera.hpp:80
int m_raw_height
The height of the frame, according to the framegrabber.
Definition: edtCamera.hpp:86
int pdvAcquire(timespec &currImageTimestamp)
Definition: edtCamera.hpp:506
int pdvSerialWriteRead(std::string &response, const std::string &command)
Send a serial command over cameralink and retrieve the response.
Definition: edtCamera.hpp:264
void setupConfig(mx::app::appConfigurator &config)
Setup the configuration system.
Definition: edtCamera.hpp:436
void loadConfig(mx::app::appConfigurator &config)
load the configuration system results
Definition: edtCamera.hpp:446
int onPowerOff()
Actions on power off.
Definition: edtCamera.hpp:480
int updateINDI()
The static callback function to be registered for the channel properties.
Definition: edtCamera.hpp:541
int appShutdown()
Application the shutdown.
Definition: edtCamera.hpp:492
int whilePowerOff()
Actions while powered off.
Definition: edtCamera.hpp:486
timespec m_currImageTimestamp
The timestamp of the current image.
uint32_t m_width
The width of the image, once deinterlaced etc.
int appShutdown()
Shuts down the framegrabber thread.
int loadConfig(mx::app::appConfigurator &config)
load the configuration system results
int updateINDI()
Update the INDI properties for this device controller.
int onPowerOff()
On power off, sets m_reconfig to true.
uint8_t m_dataType
The ImageStreamIO type code.
bool m_reconfig
Flag to set if a camera reconfiguration requires a framegrabber reset.
uint32_t m_height
The height of the image, once deinterlaced etc.
int setupConfig(mx::app::appConfigurator &config)
Setup the configuration system.
MagAO-X standard camera interface.
Definition: stdCamera.hpp:287
float m_maxEMGain
The configurable maximum EM gain. To be enforced in derivedT.
Definition: stdCamera.hpp:351
float m_fpsSet
The commanded fps, as set by user.
Definition: stdCamera.hpp:375
bool m_synchroSet
Target status of m_synchro.
Definition: stdCamera.hpp:386
std::string m_tempControlStatusStr
Camera specific description of temperature control status.
Definition: stdCamera.hpp:322
float m_emGain
The camera's current EM gain (if available).
Definition: stdCamera.hpp:349
float m_emGainSet
The camera's EM gain, as set by the user.
Definition: stdCamera.hpp:350
std::string m_nextMode
The mode to be set by the next reconfiguration.
Definition: stdCamera.hpp:400
void setupConfig(mx::app::appConfigurator &config)
Setup the configuration system.
Definition: stdCamera.hpp:1035
float m_ccdTempSetpt
The desired temperature, in C.
Definition: stdCamera.hpp:315
bool m_tempControlStatus
Whether or not temperature control is active.
Definition: stdCamera.hpp:317
std::string m_modeName
The current mode name.
Definition: stdCamera.hpp:398
float m_startupTemp
The temperature to set after a power-on. Set to <= -999 to not use [default].
Definition: stdCamera.hpp:298
bool m_synchro
Status of synchronization, true is on, false is off.
Definition: stdCamera.hpp:388
float m_ccdTemp
The current temperature, in C.
Definition: stdCamera.hpp:313
int updateINDI()
Update the INDI properties for this device controller.
Definition: stdCamera.hpp:2794
bool m_tempControlOnTarget
Whether or not the temperature control system is on its target temperature.
Definition: stdCamera.hpp:320
cameraConfigMap m_cameraModes
Map holding the possible camera mode configurations.
Definition: stdCamera.hpp:294
void loadConfig(mx::app::appConfigurator &config)
load the configuration system results
Definition: stdCamera.hpp:1074
int whilePowerOff()
Actions while powered off.
Definition: stdCamera.hpp:1710
int appShutdown()
Application shutdown.
Definition: stdCamera.hpp:1742
bool m_tempControlStatusSet
Desired state of temperature control.
Definition: stdCamera.hpp:318
int onPowerOff()
Actions on power off.
Definition: stdCamera.hpp:1647
static constexpr bool c_stdCamera_fps
app::dev config to tell stdCamera not to expose FPS status (ignored since fpsCtrl==true)
Definition: ocam2KCtrl.hpp:77
INDI_SETCALLBACK_DECL(ocam2KCtrl, m_indiP_syncFreq)
pcf::IndiProperty m_indiP_temps
Definition: ocam2KCtrl.hpp:321
static constexpr bool c_stdCamera_usesModes
app:dev config to tell stdCamera not to expose mode controls
Definition: ocam2KCtrl.hpp:81
int resetEMProtection()
Reset the EM Protection.
bool m_protectionReset
Flag indicating that protection has been reset at least once.
Definition: ocam2KCtrl.hpp:116
int setShutter(int sh)
Sets the shutter state, via call to dssShutter::setShutterState(int) [stdCamera interface].
mx::improc::eigenImage< int16_t > m_digitalBinWork
Definition: ocam2KCtrl.hpp:132
std::string stateString()
virtual int appLogic()
Implementation of the FSM for the OCAM 2K.
Definition: ocam2KCtrl.hpp:474
int recordTelem(const ocam_temps *)
static constexpr bool c_stdCamera_usesStateString
app::dev confg to tell stdCamera to expose the state string property
Definition: ocam2KCtrl.hpp:89
static constexpr bool c_stdCamera_exptimeCtrl
app::dev config to tell stdCamera not to expose exposure time controls
Definition: ocam2KCtrl.hpp:73
int setNextROI()
Required by stdCamera, but this does not do anything for this camera [stdCamera interface].
virtual void setupConfig()
Setup the configuration system (called by MagAOXApp::setup())
Definition: ocam2KCtrl.hpp:371
pcf::IndiProperty m_indiP_emProtReset
Definition: ocam2KCtrl.hpp:323
~ocam2KCtrl() noexcept
Destructor.
Definition: ocam2KCtrl.hpp:365
virtual int onPowerOff()
Implementation of the on-power-off FSM logic.
Definition: ocam2KCtrl.hpp:637
std::string m_ocamDescrambleFile
Path the OCAM 2K pixel descrambling file, relative to MagAO-X config directory.
Definition: ocam2KCtrl.hpp:104
ocamTemps m_temps
Structure holding the last temperature measurement.
Definition: ocam2KCtrl.hpp:124
static constexpr bool c_edtCamera_relativeConfigPath
app::dev config to tell edtCamera to use relative path to camera config file
Definition: ocam2KCtrl.hpp:91
int powerOnDefaults()
Set defaults for a power on state.
Definition: ocam2KCtrl.hpp:806
int setSynchro()
Set the synchro state. [stdCamera interface].
Definition: ocam2KCtrl.hpp:983
virtual int appShutdown()
Do any needed shutdown tasks.
Definition: ocam2KCtrl.hpp:706
static constexpr bool c_stdCamera_synchro
app::dev config to tell stdCamera to expose synchro mode controls
Definition: ocam2KCtrl.hpp:79
int getEMGain()
Get the current EM Gain.
unsigned m_protectionResetConfirmed
Counter indicating the number of times that the protection reset has been requested within 10 seconds...
Definition: ocam2KCtrl.hpp:118
virtual void loadConfig()
load the configuration system results (called by MagAOXApp::setup())
Definition: ocam2KCtrl.hpp:388
int setExpTime()
Required by stdCamera, but this does not do anything for this camera [stdCamera interface].
float fps()
Implementation of the frameGrabber fps interface.
int loadImageIntoStream(void *dest)
Implementation of the framegrabber loadImageIntoStream interface.
int setTempControl()
Turn temperature control on or off.
Definition: ocam2KCtrl.hpp:816
pcf::IndiProperty m_indiP_emProt
Definition: ocam2KCtrl.hpp:322
int reconfig()
Implementation of the framegrabber reconfig interface.
static constexpr bool c_stdCamera_emGain
app::dev config to tell stdCamera to expose EM gain controls
Definition: ocam2KCtrl.hpp:71
long m_currImageNumber
The current image number, retrieved from the image itself.
Definition: ocam2KCtrl.hpp:112
int setTempSetPt()
Set the CCD temperature setpoint [stdCamera interface].
Definition: ocam2KCtrl.hpp:868
static constexpr bool c_stdCamera_vShiftSpeed
app:dev config to tell stdCamera not to expose vertical shift speed control
Definition: ocam2KCtrl.hpp:69
std::string m_syncFreqProp
Definition: ocam2KCtrl.hpp:135
int startAcquisition()
Implementation of the framegrabber startAcquisition interface.
static constexpr bool c_stdCamera_tempControl
app::dev config to tell stdCamera to expose temperature controls
Definition: ocam2KCtrl.hpp:63
int setEMGain()
Set the EM gain.
INDI_NEWCALLBACK_DECL(ocam2KCtrl, m_indiP_emProtReset)
int setFPS()
Set the frame rate. [stdCamera interface].
Definition: ocam2KCtrl.hpp:936
static constexpr bool c_stdCamera_temp
app::dev config to tell stdCamera to expose temperature (ignored since tempControl==true)
Definition: ocam2KCtrl.hpp:65
static constexpr bool c_stdCamera_usesROI
app:dev config to tell stdCamera to expose ROI controls
Definition: ocam2KCtrl.hpp:83
int recordTemps(bool force=false)
int getFPS()
Get the current frame rate.
Definition: ocam2KCtrl.hpp:900
int configureAcquisition()
Implementation of the framegrabber configureAcquisition interface.
double m_protectionResetReqTime
The time at which protection reset was requested. You have 10 seconds to confirm.
Definition: ocam2KCtrl.hpp:120
ocam2KCtrl()
Default c'tor.
Definition: ocam2KCtrl.hpp:350
int acquireAndCheckValid()
Implementation of the framegrabber acquireAndCheckValid interface.
static constexpr bool c_stdCamera_fpsCtrl
app::dev config to tell stdCamera to expose FPS controls
Definition: ocam2KCtrl.hpp:75
static constexpr bool c_stdCamera_cropMode
app:dev config to tell stdCamera to expose Crop Mode controls
Definition: ocam2KCtrl.hpp:85
static constexpr bool c_frameGrabber_flippable
app:dev config to tell framegrabber these images can not be flipped
Definition: ocam2KCtrl.hpp:93
static constexpr bool c_stdCamera_readoutSpeed
app::dev config to tell stdCamera not to expose readout speed controls
Definition: ocam2KCtrl.hpp:67
ocam2_id m_ocam2_id
OCAM SDK id.
Definition: ocam2KCtrl.hpp:110
virtual int whilePowerOff()
Implementation of the while-powered-off FSM.
Definition: ocam2KCtrl.hpp:683
long m_lastImageNumber
The last image number, saved from the last loop through.
Definition: ocam2KCtrl.hpp:114
int getTemps()
Get the current device temperatures.
Definition: ocam2KCtrl.hpp:725
virtual int appStartup()
Startup functions.
Definition: ocam2KCtrl.hpp:413
static constexpr bool c_stdCamera_hasShutter
app:dev config to tell stdCamera to expose shutter controls
Definition: ocam2KCtrl.hpp:87
pcf::IndiProperty m_indiP_syncFreq
Definition: ocam2KCtrl.hpp:325
#define REG_INDI_NEWPROP_NOCB(prop, propName, type)
Register a NEW INDI property with the class, with no callback.
Definition: indiMacros.hpp:248
#define INDI_NEWCALLBACK(prop)
Get the name of the static callback wrapper for a new property.
Definition: indiMacros.hpp:208
#define REG_INDI_SETPROP(prop, devName, propName)
Register a SET INDI property with the class, using the standard callback name.
Definition: indiMacros.hpp:282
@ OPERATING
The device is operating, other than homing.
Definition: stateCodes.hpp:55
@ ERROR
The application has encountered an error, from which it is recovering (with or without intervention)
Definition: stateCodes.hpp:43
@ READY
The device is ready for operation, but is not operating.
Definition: stateCodes.hpp:56
@ CONNECTED
The application has connected to the device or service.
Definition: stateCodes.hpp:50
@ NOTCONNECTED
The application is not connected to the device or service.
Definition: stateCodes.hpp:49
@ POWERON
The device power is on.
Definition: stateCodes.hpp:48
#define INDI_IDLE
Definition: indiUtils.hpp:28
#define INDI_BUSY
Definition: indiUtils.hpp:30
#define INDI_OK
Definition: indiUtils.hpp:29
std::ostream & cerr()
int parseFPS(float &fps, const std::string &fstr)
Parse the FPS response.
Definition: ocamUtils.hpp:94
int parseTemps(ocamTemps &temps, const std::string &tstr)
Parse the OCAM temp query and fill the ocamTemps structure.
Definition: ocamUtils.hpp:64
INDI_VALIDATE_CALLBACK_PROPS(function, ipRecv)
const pcf::IndiProperty & ipRecv
Definition: MagAOXApp.hpp:3434
int parseEMGain(unsigned &emGain, const std::string &fstr)
Parse the EM gain response.
Definition: ocamUtils.hpp:115
INDI_SETCALLBACK_DEFN(adcTracker, m_indiP_teldata)(const pcf
Definition: adcTracker.hpp:461
INDI_NEWCALLBACK_DEFN(acesxeCtrl, m_indiP_windspeed)(const pcf
Definition: acesxeCtrl.hpp:687
std::unique_lock< std::mutex > lock(m_indiMutex)
Definition: dm.hpp:24
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
constexpr static logPrioT LOG_NOTICE
A normal but significant condition.
Definition: logPriority.hpp:46
MagAOX::app::MagAOXApp< true > MagAOXAppT
Definition: ocam2KCtrl.hpp:20
ocam2_rc ocam2_init(ocam2_mode mode, const char *descrbFile, ocam2_id *id)
Create a camera instance with the provided mode.
Definition: ocam2_sdk.c:431
void ocam2_descramble(ocam2_id id, unsigned int *number, short *image, const short *imageRaw)
Create a camera instance with the provided mode.
Definition: ocam2_sdk.c:418
const char * ocam2_modeStr(ocam2_mode mode)
Return a description text for camera mode.
Definition: ocam2_sdk.c:77
ocam2_rc ocam2_exit(ocam2_id id)
Clear a camera instance.
Definition: ocam2_sdk.c:490
ocam2_mode ocam2_getMode(ocam2_id id)
Return the camera mode.
Definition: ocam2_sdk.c:69
The purpose of the libocam2sdk library is to provide an easy way to achieve ocam2 specific opération....
int ocam2_id
Library camera identifier.
Definition: ocam2_sdk.h:268
ocam2_rc
Enum of ocam2 library return code.
Definition: ocam2_sdk.h:258
@ OCAM2_OK
Definition: ocam2_sdk.h:260
@ OCAM2_BINNING
Definition: ocam2_sdk.h:236
@ OCAM2_BINNING1x3
Definition: ocam2_sdk.h:244
@ OCAM2_BINNING1x4
Definition: ocam2_sdk.h:246
@ OCAM2_NORMAL
Definition: ocam2_sdk.h:226
enum workMode ocam2_mode
typedef of ocam2 camera mode
#define OCAM2_IMAGE_NB_OFFSET
Definition: ocam2_sdk.h:208
Utilities for the OCAM camera.
A device base class which saves telemetry.
Definition: telemeter.hpp:69
int appShutdown()
Perform telemeter application shutdown.
Definition: telemeter.hpp:274
int loadConfig(appConfigurator &config)
Load the device section from an application configurator.
Definition: telemeter.hpp:223
int appLogic()
Perform telemeter application logic.
Definition: telemeter.hpp:268
int setupConfig(appConfigurator &config)
Setup an application configurator for the device section.
Definition: telemeter.hpp:211
int checkRecordTimes(const telT &tel, telTs... tels)
Check the time of the last record for each telemetry type and make an entry if needed.
Definition: telemeter.hpp:281
Structure to hold the OCAM camera temperature readings returned by the device.
Definition: ocamUtils.hpp:20
float WATER
Cooling water temperature.
Definition: ocamUtils.hpp:25
int setInvalid()
Set all values to the invalid value, -999.
Definition: ocamUtils.hpp:43
float COOLING_POWER
the cooling power in 100 mw.
Definition: ocamUtils.hpp:29
float BIAS
Bias temperature.
Definition: ocamUtils.hpp:24
float SET
The CCD set temeperature.
Definition: ocamUtils.hpp:28
float CCD
The detector temperature.
Definition: ocamUtils.hpp:21
float POWER
Power supply temperature.
Definition: ocamUtils.hpp:23
float CPU
The CPU temperature.
Definition: ocamUtils.hpp:22
float LEFT
The left amplifier temperature.
Definition: ocamUtils.hpp:26
float RIGHT
The right amplifier temperature.
Definition: ocamUtils.hpp:27
Log entry recording the build-time git state.
Definition: ocam_temps.hpp:26
Software CRITICAL log entry.
Software ERR log entry.
Log entry recording framegrabber timings.
Log entry recording stdcam stage specific status.
A simple text log, a string-type log.
Definition: text_log.hpp:24