API
 
Loading...
Searching...
No Matches
pwfsSlopeCalc.hpp
Go to the documentation of this file.
1/** \file pwfsSlopeCalc.hpp
2 * \brief The MagAO-X PWFS Slope Calculator
3 *
4 * \ingroup app_files
5 */
6
7#ifndef pwfsSlopeCalc_hpp
8#define pwfsSlopeCalc_hpp
9
10#include <limits>
11
12#include <mx/improc/eigenCube.hpp>
13#include <mx/improc/eigenImage.hpp>
14using namespace mx::improc;
15
16#include "../../libMagAOX/libMagAOX.hpp" //Note this is included on command line to trigger pch
17#include "../../magaox_git_version.h"
18
19namespace MagAOX
20{
21namespace app
22{
23
24struct darkShmimT
25{
26 static std::string configSection()
27 {
28 return "darkShmim";
29 };
30
31 static std::string indiPrefix()
32 {
33 return "dark";
34 };
35};
36
37
38/** \defgroup pwfsSlopeCalc PWFS Slope Calculator
39 * \brief Calculates slopes from a PWFS image.
40 *
41 * <a href="../handbook/operating/software/apps/pwfsSlopeCalc.html">Application Documentation</a>
42 *
43 * \ingroup apps
44 *
45 */
46
47/** \defgroup pwfsSlopeCalc_files PWFS Slope Calculator Files
48 * \ingroup pwfsSlopeCalc
49 */
50
51/** MagAO-X application to calculate slopes from PWFS images.
52 *
53 * \ingroup pwfsSlopeCalc
54 *
55 */
56class pwfsSlopeCalc : public MagAOXApp<true>, public dev::shmimMonitor<pwfsSlopeCalc>, public dev::shmimMonitor<pwfsSlopeCalc,darkShmimT>, public dev::frameGrabber<pwfsSlopeCalc>, public dev::telemeter<pwfsSlopeCalc>
57{
58
59 //Give the test harness access.
60 friend class pwfsSlopeCalc_test;
61
62 friend class dev::shmimMonitor<pwfsSlopeCalc>;
64 friend class dev::frameGrabber<pwfsSlopeCalc>;
65 friend class dev::telemeter<pwfsSlopeCalc>;
66
67 //The base shmimMonitor type
69
70 //The dark shmimMonitor type
72
73 //The base frameGrabber type
75
76 //The base telemeter type
78
79 ///Floating point type in which to do all calculations.
80 typedef float realT;
81
82 static constexpr bool c_frameGrabber_flippable = false; ///< app:dev config to tell framegrabber these images can not be flipped
83
84protected:
85
86 /** \name Configurable Parameters
87 *@{
88 */
89
90 std::string m_fitter; ///< Device name of the pupil fitter process. If set, the number of pupils
91 int m_numPupils {4};
92
93 float m_pupil_cx_1; ///< the center x coordinate of pupil 1
94 float m_pupil_cy_1; ///< the center y coordinate of pupil 1
95 float m_pupil_D_1 {0}; ///< the diameter of pupil 1, used only for averaging the fitter output
96
97 float m_pupil_cx_2; ///< the center x coordinate of pupil 2
98 float m_pupil_cy_2; ///< the center y coordinate of pupil 2
99 float m_pupil_D_2 {0}; ///< the diameter of pupil 2, used only for averaging the fitter output
100
101 float m_pupil_cx_3; ///< the center x coordinate of pupil 3
102 float m_pupil_cy_3; ///< the center y coordinate of pupil 3
103 float m_pupil_D_3 {0}; ///< the diameter of pupil 3, used only for averaging the fitter output
104
105 float m_pupil_cx_4; ///< the center x coordinate of pupil 4
106 float m_pupil_cy_4; ///< the center y coordinate of pupil 4
107 float m_pupil_D_4 {0}; ///< the diameter of pupil 4, used only for averaging the fitter output
108
109 int m_pupil_D {56}; ///< the pupil diameter, just one applied to all pupils.
110
111 int m_pupil_buffer {1}; ///< the edge buffer for the pupils, just one applied to all pupils. Default is 1.
112
113 ///@}
114
115 sem_t m_smSemaphore; ///< Semaphore used to synchronize the fg thread and the sm thread.
116
117 realT (*pixget)(void *, size_t) {nullptr}; ///< Pointer to a function to extract the image data as our desired type realT.
118
119 void * m_curr_src {nullptr};
120
121 int m_quadSize {60};
122
123 mx::improc::eigenImage<realT> m_darkImage;
124 realT (*dark_pixget)(void *, size_t) {nullptr}; ///< Pointer to a function to extract the image data as our desired type realT.
125 bool m_darkSet {false};
126
127 int m_pupil_sx_1; ///< the starting x-coordinate of pupil 1 quadrant, calculated from the pupil center, diameter, and buffer.
128 int m_pupil_sy_1; ///< the starting y-coordinate of pupil 1 quadrant, calculated from the pupil center, diameter, and buffer.
129
130 int m_pupil_sx_2; ///< the starting x-coordinate of pupil 2 quadrant, calculated from the pupil center, diameter, and buffer.
131 int m_pupil_sy_2; ///< the starting y-coordinate of pupil 2 quadrant, calculated from the pupil center, diameter, and buffer.
132
133 int m_pupil_sx_3; ///< the starting x-coordinate of pupil 3 quadrant, calculated from the pupil center, diameter, and buffer.
134 int m_pupil_sy_3; ///< the starting y-coordinate of pupil 3 quadrant, calculated from the pupil center, diameter, and buffer.
135
136 int m_pupil_sx_4; ///< the starting x-coordinate of pupil 4 quadrant, calculated from the pupil center, diameter, and buffer.
137 int m_pupil_sy_4; ///< the starting y-coordinate of pupil 4 quadrant, calculated from the pupil center, diameter, and buffer.
138
139public:
140 /// Default c'tor.
142
143 /// D'tor, declared and defined for noexcept.
146
147 virtual void setupConfig();
148
149 /// Implementation of loadConfig logic, separated for testing.
150 /** This is called by loadConfig().
151 */
152 int loadConfigImpl( mx::app::appConfigurator & _config /**< [in] an application configuration from which to load values*/);
153
154 virtual void loadConfig();
155
156 /// Startup function
157 /**
158 *
159 */
160 virtual int appStartup();
161
162 /// Implementation of the FSM for pwfsSlopeCalc.
163 /**
164 * \returns 0 on no critical error
165 * \returns -1 on an error requiring shutdown
166 */
167 virtual int appLogic();
168
169 /// Shutdown the app.
170 /**
171 *
172 */
173 virtual int appShutdown();
174
175 int allocate( const dev::shmimT & dummy /**< [in] tag to differentiate shmimMonitor parents.*/);
176
177 int processImage( void * curr_src, ///< [in] pointer to start of current frame.
178 const dev::shmimT & dummy ///< [in] tag to differentiate shmimMonitor parents.
179 );
180
181 int allocate( const darkShmimT & dummy /**< [in] tag to differentiate shmimMonitor parents.*/);
182
183 int processImage( void * curr_src, ///< [in] pointer to start of current frame.
184 const darkShmimT & dummy ///< [in] tag to differentiate shmimMonitor parents.
185 );
186
187 float fps()
188 {
189 return 250;
190 }
191
192protected:
193
194 /** \name dev::frameGrabber interface
195 *
196 * @{
197 */
198
199 /// Implementation of the framegrabber configureAcquisition interface
200 /**
201 * \returns 0 on success
202 * \returns -1 on error
203 */
205
206 /// Implementation of the framegrabber startAcquisition interface
207 /**
208 * \returns 0 on success
209 * \returns -1 on error
210 */
211 int startAcquisition();
212
213 /// Implementation of the framegrabber acquireAndCheckValid interface
214 /**
215 * \returns 0 on success
216 * \returns -1 on error
217 */
219
220 /// Implementation of the framegrabber loadImageIntoStream interface
221 /**
222 * \returns 0 on success
223 * \returns -1 on error
224 */
225 int loadImageIntoStream( void * dest /**< [in] */);
226
227 /// Implementation of the framegrabber reconfig interface
228 /**
229 * \returns 0 on success
230 * \returns -1 on error
231 */
232 int reconfig();
233
234 ///@}
235
236 pcf::IndiProperty m_indiP_quad1;
237 pcf::IndiProperty m_indiP_quad2;
238 pcf::IndiProperty m_indiP_quad3;
239 pcf::IndiProperty m_indiP_quad4;
240
241public:
246
247 /** \name Telemeter Interface
248 *
249 * @{
250 */
251 int checkRecordTimes();
252
253 int recordTelem( const telem_fgtimings * );
254
255 ///@}
256};
257
258
259inline
260pwfsSlopeCalc::pwfsSlopeCalc() : MagAOXApp(MAGAOX_CURRENT_SHA1, MAGAOX_REPO_MODIFIED)
261{
263 return;
264}
265
266inline
268{
271
274
275 config.add("pupil.fitter", "", "pupil.fitter", argType::Required, "pupil", "fitter", false, "int", "The device name of the pupil fitter. If set, then pupil position is set by the fitter reference.");
276
277 config.add("pupil.D", "", "pupil.D", argType::Required, "pupil", "D", false, "int", "The diameter of the pupils, fixed. Default is 56.");
278
279 config.add("pupil.buffer", "", "pupil.buffer", argType::Required, "pupil", "buffer", false, "int", "The edge buffer for the pupils. Default is 1.");
280
281 config.add("pupil.numPupils", "", "pupil.numPupils", argType::Required, "pupil", "numPupils", false, "int", "The number of pupils. Default is 4. 3 is also supported.");
282
283
284
285 config.add("pupil.cx_1", "", "pupil.cx_1", argType::Required, "pupil", "cx_1", false, "int", "The default x-coordinate of pupil 1 (LL). Can be updated from real-time fitter.");
286 config.add("pupil.cy_1", "", "pupil.cy_1", argType::Required, "pupil", "cy_1", false, "int", "The default y-coordinate of pupil 1 (LL). Can be updated from real-time fitter.");
287
288 config.add("pupil.cx_2", "", "pupil.cx_2", argType::Required, "pupil", "cx_2", false, "int", "The default x-coordinate of pupil 2 (LL). Can be updated from real-time fitter.");
289 config.add("pupil.cy_2", "", "pupil.cy_2", argType::Required, "pupil", "cy_2", false, "int", "The default y-coordinate of pupil 2 (LL). Can be updated from real-time fitter.");
290
291 config.add("pupil.cx_3", "", "pupil.cx_3", argType::Required, "pupil", "cx_3", false, "int", "The default x-coordinate of pupil 3 (LL). Can be updated from real-time fitter.");
292 config.add("pupil.cy_3", "", "pupil.cy_3", argType::Required, "pupil", "cy_3", false, "int", "The default y-coordinate of pupil 3 (LL). Can be updated from real-time fitter.");
293
294 config.add("pupil.cx_4", "", "pupil.cx_4", argType::Required, "pupil", "cx_4", false, "int", "The default x-coordinate of pupil 4 (LL). Can be updated from real-time fitter.");
295 config.add("pupil.cy_4", "", "pupil.cy_4", argType::Required, "pupil", "cy_4", false, "int", "The default y-coordinate of pupil 4 (LL). Can be updated from real-time fitter.");
296}
297
298inline
299int pwfsSlopeCalc::loadConfigImpl( mx::app::appConfigurator & _config )
300{
301
306
307 config(m_fitter, "pupil.fitter");
308 config(m_numPupils, "pupil.numPupils");
309 config(m_pupil_D, "pupil.D");
310 config(m_pupil_buffer, "pupil.buffer");
311 config(m_pupil_cx_1, "pupil.cx_1");
312 config(m_pupil_cy_1, "pupil.cy_1");
313 config(m_pupil_cx_2, "pupil.cx_2");
314 config(m_pupil_cy_2, "pupil.cy_2");
315 config(m_pupil_cx_3, "pupil.cx_3");
316 config(m_pupil_cy_3, "pupil.cy_3");
317 config(m_pupil_cx_4, "pupil.cx_4");
318 config(m_pupil_cy_4, "pupil.cy_4");
319 return 0;
320}
321
322inline
324{
325 loadConfigImpl(config);
326}
327
328inline
330{
331 if(sem_init(&m_smSemaphore, 0,0) < 0)
332 {
333 log<software_critical>({__FILE__, __LINE__, errno,0, "Initializing S.M. semaphore"});
334 return -1;
335 }
336
338 {
339 return log<software_error,-1>({__FILE__, __LINE__});
340 }
341
343 {
344 return log<software_error,-1>({__FILE__, __LINE__});
345 }
346
348 {
349 return log<software_error,-1>({__FILE__, __LINE__});
350 }
351
352 if(telemeterT::appStartup() < 0)
353 {
354 return log<software_error,-1>({__FILE__, __LINE__});
355 }
356
357 if(m_fitter != "")
358 {
362 if(m_numPupils == 4)
363 {
365 }
366 }
367
369
370 return 0;
371}
372
373inline
375{
376 if( shmimMonitorT::appLogic() < 0)
377 {
378 return log<software_error,-1>({__FILE__,__LINE__});
379 }
380
381 if( darkMonitorT::appLogic() < 0)
382 {
383 return log<software_error,-1>({__FILE__,__LINE__});
384 }
385
386
387 if( frameGrabberT::appLogic() < 0)
388 {
389 return log<software_error,-1>({__FILE__,__LINE__});
390 }
391
392 if( telemeterT::appLogic() < 0)
393 {
394 return log<software_error,-1>({__FILE__,__LINE__});
395 }
396
397 std::unique_lock<std::mutex> lock(m_indiMutex);
398
400 {
402 }
403
405 {
407 }
408
410 {
412 }
413
414
415
416
417 return 0;
418}
419
420inline
433
434inline
436{
437 static_cast<void>(dummy); //be unused
438
439 //Initialize dark image if not correct size.
441 {
443 m_darkImage.setZero();
444 m_darkSet = false;
445 }
446
447 m_reconfig = true;
448
449 return 0;
450}
451
452inline
453int pwfsSlopeCalc::processImage( void * curr_src,
454 const dev::shmimT & dummy
455 )
456{
457 static_cast<void>(dummy); //be unused
458
460
461 //Now tell the f.g. to get going
462 if(sem_post(&m_smSemaphore) < 0)
463 {
464 log<software_critical>({__FILE__, __LINE__, errno, 0, "Error posting to semaphore"});
465 return -1;
466 }
467
468 return 0;
469}
470
471inline
473{
474 static_cast<void>(dummy); //be unused
475
476 m_darkSet = false;
477
478// if(darkMonitorT::m_width != shmimMonitorT::m_width || darkMonitorT::m_height != shmimMonitorT::m_height)
479// {
480// darkMonitorT::m_restart = true;
481// }
482
485
486 if(dark_pixget == nullptr)
487 {
488 log<software_error>({__FILE__, __LINE__, "bad data type"});
489 return -1;
490 }
491
492 return 0;
493}
494
495inline
496int pwfsSlopeCalc::processImage( void * curr_src,
497 const darkShmimT & dummy
498 )
499{
500 static_cast<void>(dummy); //be unused
501
502 realT * data = m_darkImage.data();
503
505 {
506 //data[nn] = *( (int16_t * ) (curr_src + nn*shmimMonitorT::m_typeSize));
507 data[nn] = dark_pixget(curr_src, nn);
508 }
509
510 m_darkSet = true;
511
512 return 0;
513}
514
515inline
517{
518 std::unique_lock<std::mutex> lock(m_indiMutex);
519
521 {
522 //This means we haven't connected to the stream to average. so wait.
523 sleep(1);
524 return -1;
525 }
526
528
531
534
537
540
541 //m_quadSize = shmimMonitorT::m_width/2;
545
546 return 0;
547}
548
549inline
551{
552 return 0;
553}
554
555inline
557{
558 timespec ts;
559
561 {
562 log<software_critical>({__FILE__,__LINE__,errno,0,"clock_gettime"});
563 return -1;
564 }
565
566 ts.tv_sec += 1;
567
568 if(sem_timedwait(&m_smSemaphore, &ts) == 0)
569 {
571 return 0;
572 }
573 else
574 {
575 return 1;
576 }
577}
578
579inline
581{
582 //Here is where we do it.
583 Eigen::Map<eigenImage<unsigned short>> pwfsIm( static_cast<unsigned short *>(m_curr_src), shmimMonitorT::m_width, shmimMonitorT::m_height );
584 Eigen::Map<eigenImage<float>> slopesIm(static_cast<float*>(dest), frameGrabberT::m_width, frameGrabberT::m_height );
585
586 static float sqrt32 = sqrt(3.0)/2;
587
588 float norm = 0;
589 int N = 0;
590 if(m_numPupils == 3)
591 {
592 for(int rr=0; rr< m_quadSize; ++rr)
593 {
594 for(int cc=0; cc< m_quadSize; ++cc)
595 {
599
600 norm += I1+I2+I3;
601 ++N;
602
603 slopesIm(rr,cc) = sqrt32*(I2-I3);///norm;
604 slopesIm(rr,cc+m_quadSize) = (I1-0.5*(I2+I3));///norm;
605 }
606 }
607 }
608 else
609 {
610
611 for(int rr=0; rr< m_quadSize; ++rr)
612 {
613 for(int cc=0; cc< m_quadSize; ++cc)
614 {
619
620 norm += I1+I2+I3+I4;
621 ++N;
622
623 slopesIm(rr,cc) = ((I1+I3) - (I2+I4));///norm;
624 slopesIm(rr,cc+m_quadSize) = ((I1+I2)-(I3+I4));///norm;
625 }
626 }
627 }
628
629 norm /= N;
630 for(size_t ii=0; ii< frameGrabberT::m_height; ++ii)
631 {
632 for(size_t jj=0; jj < frameGrabberT::m_width; ++jj)
633 {
634 slopesIm(jj,ii)/=norm;
635 }
636 }
637
638 return 0;
639}
640
641inline
643{
644 return 0;
645}
646
647INDI_SETCALLBACK_DEFN(pwfsSlopeCalc, m_indiP_quad1)(const pcf::IndiProperty &ipRecv)
648{
649 if(ipRecv.getName() != m_indiP_quad1.getName())
650 {
651 log<software_error>({__FILE__,__LINE__,"wrong INDI property received"});
652
653 return -1;
654 }
655
656 if(ipRecv.find("set-x"))
657 {
658 float newval = ipRecv["set-x"].get<float>();
659 if(newval != m_pupil_cx_1)
660 {
661 m_pupil_cx_1 = newval;
662 m_reconfig = true;
663 }
664 }
665
666 if(ipRecv.find("set-y"))
667 {
668 float newval = ipRecv["set-y"].get<float>();
669 if(newval != m_pupil_cy_1)
670 {
671 m_pupil_cy_1 = newval;
672 m_reconfig = true;
673 }
674 }
675
676 if(ipRecv.find("set-D"))
677 {
678 float newval = ipRecv["set-D"].get<float>();
679 if(newval != m_pupil_D_1)
680 {
681 m_pupil_D_1 = newval;
682 m_reconfig = true;
683 }
684 }
685
686
687 return 0;
688}
689
690INDI_SETCALLBACK_DEFN(pwfsSlopeCalc, m_indiP_quad2)(const pcf::IndiProperty &ipRecv)
691{
692 if(ipRecv.getName() != m_indiP_quad2.getName())
693 {
694 log<software_error>({__FILE__,__LINE__,"wrong INDI property received"});
695
696 return -2;
697 }
698
699 if(ipRecv.find("set-x"))
700 {
701 float newval = ipRecv["set-x"].get<float>();
702 if(newval != m_pupil_cx_2)
703 {
704 m_pupil_cx_2 = newval;
705 m_reconfig = true;
706 }
707 }
708
709 if(ipRecv.find("set-y"))
710 {
711 float newval = ipRecv["set-y"].get<float>();
712 if(newval != m_pupil_cy_2)
713 {
714 m_pupil_cy_2 = newval;
715 m_reconfig = true;
716 }
717 }
718 if(ipRecv.find("set-D"))
719 {
720 float newval = ipRecv["set-D"].get<float>();
721 if(newval != m_pupil_D_2)
722 {
723 m_pupil_D_2 = newval;
724 m_reconfig = true;
725 }
726 }
727
728
729 return 0;
730}
731
732INDI_SETCALLBACK_DEFN(pwfsSlopeCalc, m_indiP_quad3)(const pcf::IndiProperty &ipRecv)
733{
734 if(ipRecv.getName() != m_indiP_quad3.getName())
735 {
736 log<software_error>({__FILE__,__LINE__,"wrong INDI property received"});
737
738 return -3;
739 }
740
741 if(ipRecv.find("set-x"))
742 {
743 float newval = ipRecv["set-x"].get<float>();
744 if(newval != m_pupil_cx_3)
745 {
746 m_pupil_cx_3 = newval;
747 m_reconfig = true;
748 }
749 }
750 if(ipRecv.find("set-y"))
751 {
752 float newval = ipRecv["set-y"].get<float>();
753 if(newval != m_pupil_cy_3)
754 {
755 m_pupil_cy_3 = newval;
756 m_reconfig = true;
757 }
758 }
759 if(ipRecv.find("set-D"))
760 {
761 float newval = ipRecv["set-D"].get<float>();
762 if(newval != m_pupil_D_3)
763 {
764 m_pupil_D_3 = newval;
765 m_reconfig = true;
766 }
767 }
768
769
770 return 0;
771}
772
773INDI_SETCALLBACK_DEFN(pwfsSlopeCalc, m_indiP_quad4)(const pcf::IndiProperty &ipRecv)
774{
775 if(ipRecv.getName() != m_indiP_quad4.getName())
776 {
777 log<software_error>({__FILE__,__LINE__,"wrong INDI property received"});
778
779 return -4;
780 }
781
782 if(ipRecv.find("set-x"))
783 {
784 float newval = ipRecv["set-x"].get<float>();
785 if(newval != m_pupil_cx_4)
786 {
787 m_pupil_cx_4 = newval;
788 m_reconfig = true;
789 }
790 }
791 if(ipRecv.find("set-y"))
792 {
793 float newval = ipRecv["set-y"].get<float>();
794 if(newval != m_pupil_cy_4)
795 {
796 m_pupil_cy_4 = newval;
797 m_reconfig = true;
798 }
799 }
800 if(ipRecv.find("set-D"))
801 {
802 float newval = ipRecv["set-D"].get<float>();
803 if(newval != m_pupil_D_4)
804 {
805 m_pupil_D_4 = newval;
806 m_reconfig = true;
807 }
808 }
809
810
811 return 0;
812}
813
814inline
819
820inline
822{
823 return recordFGTimings(true);
824}
825
826} //namespace app
827} //namespace MagAOX
828
829#endif //pwfsSlopeCalc_hpp
The base-class for MagAO-X applications.
Definition MagAOXApp.hpp:73
stateCodes::stateCodeT state()
Get the current state code.
static int log(const typename logT::messageT &msg, logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry.
std::mutex m_indiMutex
Mutex for locking INDI communications.
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.
uint8_t m_dataType
The ImageStreamIO type code.
bool m_reconfig
Flag to set if a camera reconfiguration requires a framegrabber reset.
int appLogic()
Checks the framegrabber thread.
uint32_t m_height
The height of the image, once deinterlaced etc.
int setupConfig(mx::app::appConfigurator &config)
Setup the configuration system.
uint32_t m_width
The width of the images in the stream.
int setupConfig(mx::app::appConfigurator &config)
Setup the configuration system.
int updateINDI()
Update the INDI properties for this device controller.
int appLogic()
Checks the shmimMonitor thread.
uint32_t m_height
The height of the images in the stream.
int appShutdown()
Shuts down the shmimMonitor thread.
int loadConfig(mx::app::appConfigurator &config)
load the configuration system results
bool m_getExistingFirst
If set to true by derivedT, any existing image will be grabbed and sent to processImage before waitin...
std::string m_fitter
Device name of the pupil fitter process. If set, the number of pupils.
float m_pupil_cy_1
the center y coordinate of pupil 1
void * m_curr_src
Pointer to a function to extract the image data as our desired type realT.
int m_pupil_sy_1
the starting y-coordinate of pupil 1 quadrant, calculated from the pupil center, diameter,...
pcf::IndiProperty m_indiP_quad2
float m_pupil_D_3
the diameter of pupil 3, used only for averaging the fitter output
float m_pupil_cx_2
the center x coordinate of pupil 2
int configureAcquisition()
Implementation of the framegrabber configureAcquisition interface.
pcf::IndiProperty m_indiP_quad1
virtual int appShutdown()
Shutdown the app.
pcf::IndiProperty m_indiP_quad4
realT(* pixget)(void *, size_t)
static constexpr bool c_frameGrabber_flippable
app:dev config to tell framegrabber these images can not be flipped
float m_pupil_cx_1
the center x coordinate of pupil 1
INDI_SETCALLBACK_DECL(pwfsSlopeCalc, m_indiP_quad4)
virtual int appStartup()
Startup function.
float m_pupil_cx_3
the center x coordinate of pupil 3
float m_pupil_D_1
the diameter of pupil 1, used only for averaging the fitter output
float realT
Floating point type in which to do all calculations.
dev::frameGrabber< pwfsSlopeCalc > frameGrabberT
INDI_SETCALLBACK_DECL(pwfsSlopeCalc, m_indiP_quad1)
int m_pupil_sx_4
the starting x-coordinate of pupil 4 quadrant, calculated from the pupil center, diameter,...
float m_pupil_cy_3
the center y coordinate of pupil 3
int m_pupil_D
the pupil diameter, just one applied to all pupils.
int m_pupil_sx_3
the starting x-coordinate of pupil 3 quadrant, calculated from the pupil center, diameter,...
realT(* dark_pixget)(void *, size_t)
virtual int appLogic()
Implementation of the FSM for pwfsSlopeCalc.
INDI_SETCALLBACK_DECL(pwfsSlopeCalc, m_indiP_quad3)
int acquireAndCheckValid()
Implementation of the framegrabber acquireAndCheckValid interface.
dev::shmimMonitor< pwfsSlopeCalc, darkShmimT > darkMonitorT
int loadImageIntoStream(void *dest)
Implementation of the framegrabber loadImageIntoStream interface.
int m_pupil_sy_2
the starting y-coordinate of pupil 2 quadrant, calculated from the pupil center, diameter,...
int allocate(const dev::shmimT &dummy)
int m_pupil_sx_2
the starting x-coordinate of pupil 2 quadrant, calculated from the pupil center, diameter,...
int m_pupil_sx_1
the starting x-coordinate of pupil 1 quadrant, calculated from the pupil center, diameter,...
int m_pupil_sy_3
the starting y-coordinate of pupil 3 quadrant, calculated from the pupil center, diameter,...
INDI_SETCALLBACK_DECL(pwfsSlopeCalc, m_indiP_quad2)
dev::telemeter< pwfsSlopeCalc > telemeterT
~pwfsSlopeCalc() noexcept
D'tor, declared and defined for noexcept.
bool m_darkSet
Pointer to a function to extract the image data as our desired type realT.
int m_pupil_sy_4
the starting y-coordinate of pupil 4 quadrant, calculated from the pupil center, diameter,...
int startAcquisition()
Implementation of the framegrabber startAcquisition interface.
pcf::IndiProperty m_indiP_quad3
float m_pupil_cx_4
the center x coordinate of pupil 4
sem_t m_smSemaphore
Semaphore used to synchronize the fg thread and the sm thread.
dev::shmimMonitor< pwfsSlopeCalc > shmimMonitorT
int reconfig()
Implementation of the framegrabber reconfig interface.
float m_pupil_cy_2
the center y coordinate of pupil 2
float m_pupil_D_4
the diameter of pupil 4, used only for averaging the fitter output
float m_pupil_cy_4
the center y coordinate of pupil 4
int loadConfigImpl(mx::app::appConfigurator &_config)
Implementation of loadConfig logic, separated for testing.
int recordTelem(const telem_fgtimings *)
int m_pupil_buffer
the edge buffer for the pupils, just one applied to all pupils. Default is 1.
float m_pupil_D_2
the diameter of pupil 2, used only for averaging the fitter output
mx::improc::eigenImage< realT > m_darkImage
int processImage(void *curr_src, const dev::shmimT &dummy)
#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.
@ OPERATING
The device is operating, other than homing.
const pcf::IndiProperty & ipRecv
std::unique_lock< std::mutex > lock(m_indiMutex)
Definition dm.hpp:24
static std::string configSection()
static std::string indiPrefix()
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 appLogic()
Perform telemeter application logic.
int setupConfig(appConfigurator &config)
Setup an application configurator for the device section.
int appStartup()
Starts the telemetry log thread.
int checkRecordTimes(const telT &tel, telTs... tels)
Check the time of the last record for each telemetry type and make an entry if needed.
Software ERR log entry.
Log entry recording framegrabber timings.