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