7 #ifndef pwfsSlopeCalc_hpp
8 #define pwfsSlopeCalc_hpp
12 #include <mx/improc/eigenCube.hpp>
13 #include <mx/improc/eigenImage.hpp>
14 using namespace mx::improc;
16 #include "../../libMagAOX/libMagAOX.hpp"
17 #include "../../magaox_git_version.h"
60 friend class pwfsSlopeCalc_test;
82 static constexpr
bool c_frameGrabber_flippable =
false;
95 float m_pupil_D_1 {0};
99 float m_pupil_D_2 {0};
103 float m_pupil_D_3 {0};
107 float m_pupil_D_4 {0};
111 int m_pupil_buffer {1};
117 realT (*pixget)(
void *, size_t) {
nullptr};
119 void * m_curr_src {
nullptr};
124 realT (*dark_pixget)(
void *, size_t) {
nullptr};
125 bool m_darkSet {
false};
147 virtual void setupConfig();
152 int loadConfigImpl( mx::app::appConfigurator & _config );
154 virtual void loadConfig();
160 virtual int appStartup();
167 virtual int appLogic();
173 virtual int appShutdown();
177 int processImage(
void * curr_src,
183 int processImage(
void * curr_src,
204 int configureAcquisition();
211 int startAcquisition();
218 int acquireAndCheckValid();
225 int loadImageIntoStream(
void * dest );
251 int checkRecordTimes();
260 pwfsSlopeCalc::pwfsSlopeCalc() :
MagAOXApp(MAGAOX_CURRENT_SHA1, MAGAOX_REPO_MODIFIED)
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.");
277 config.add(
"pupil.D",
"",
"pupil.D", argType::Required,
"pupil",
"D",
false,
"int",
"The diameter of the pupils, fixed. Default is 56.");
279 config.add(
"pupil.buffer",
"",
"pupil.buffer", argType::Required,
"pupil",
"buffer",
false,
"int",
"The edge buffer for the pupils. Default is 1.");
281 config.add(
"pupil.numPupils",
"",
"pupil.numPupils", argType::Required,
"pupil",
"numPupils",
false,
"int",
"The number of pupils. Default is 4. 3 is also supported.");
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.");
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.");
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.");
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.");
333 log<software_critical>({__FILE__, __LINE__, errno,0,
"Initializing S.M. semaphore"});
401 log<software_error>({__FILE__, __LINE__});
406 log<software_error>({__FILE__, __LINE__});
411 log<software_error>({__FILE__, __LINE__});
437 static_cast<void>(dummy);
457 static_cast<void>(dummy);
464 log<software_critical>({__FILE__, __LINE__, errno, 0,
"Error posting to semaphore"});
474 static_cast<void>(dummy);
488 log<software_error>({__FILE__, __LINE__,
"bad data type"});
500 static_cast<void>(dummy);
560 if(clock_gettime(CLOCK_REALTIME, &ts) < 0)
562 log<software_critical>({__FILE__,__LINE__,errno,0,
"clock_gettime"});
586 static float sqrt32 = sqrt(3.0)/2;
603 slopesIm(rr,cc) = sqrt32*(I2-I3);
604 slopesIm(rr,cc+
m_quadSize) = (I1-0.5*(I2+I3));
623 slopesIm(rr,cc) = ((I1+I3) - (I2+I4));
624 slopesIm(rr,cc+
m_quadSize) = ((I1+I2)-(I3+I4));
634 slopesIm(jj,ii)/=norm;
649 if(
ipRecv.getName() != m_indiP_quad1.getName())
651 log<software_error>({__FILE__,__LINE__,
"wrong INDI property received"});
658 float newval =
ipRecv[
"set-x"].get<
float>();
659 if(newval != m_pupil_cx_1)
661 m_pupil_cx_1 = newval;
668 float newval =
ipRecv[
"set-y"].get<
float>();
669 if(newval != m_pupil_cy_1)
671 m_pupil_cy_1 = newval;
678 float newval =
ipRecv[
"set-D"].get<
float>();
679 if(newval != m_pupil_D_1)
681 m_pupil_D_1 = newval;
692 if(
ipRecv.getName() != m_indiP_quad2.getName())
694 log<software_error>({__FILE__,__LINE__,
"wrong INDI property received"});
701 float newval =
ipRecv[
"set-x"].get<
float>();
702 if(newval != m_pupil_cx_2)
704 m_pupil_cx_2 = newval;
711 float newval =
ipRecv[
"set-y"].get<
float>();
712 if(newval != m_pupil_cy_2)
714 m_pupil_cy_2 = newval;
720 float newval =
ipRecv[
"set-D"].get<
float>();
721 if(newval != m_pupil_D_2)
723 m_pupil_D_2 = newval;
734 if(
ipRecv.getName() != m_indiP_quad3.getName())
736 log<software_error>({__FILE__,__LINE__,
"wrong INDI property received"});
743 float newval =
ipRecv[
"set-x"].get<
float>();
744 if(newval != m_pupil_cx_3)
746 m_pupil_cx_3 = newval;
752 float newval =
ipRecv[
"set-y"].get<
float>();
753 if(newval != m_pupil_cy_3)
755 m_pupil_cy_3 = newval;
761 float newval =
ipRecv[
"set-D"].get<
float>();
762 if(newval != m_pupil_D_3)
764 m_pupil_D_3 = newval;
775 if(
ipRecv.getName() != m_indiP_quad4.getName())
777 log<software_error>({__FILE__,__LINE__,
"wrong INDI property received"});
784 float newval =
ipRecv[
"set-x"].get<
float>();
785 if(newval != m_pupil_cx_4)
787 m_pupil_cx_4 = newval;
793 float newval =
ipRecv[
"set-y"].get<
float>();
794 if(newval != m_pupil_cy_4)
796 m_pupil_cy_4 = newval;
802 float newval =
ipRecv[
"set-D"].get<
float>();
803 if(newval != m_pupil_D_4)
805 m_pupil_D_4 = newval;
The base-class for MagAO-X applications.
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 recordFGTimings(bool force=false)
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.
int appStartup()
Startup function.
uint32_t m_height
The height of the image, once deinterlaced etc.
int setupConfig(mx::app::appConfigurator &config)
Setup the configuration system.
int appStartup()
Startup function.
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.
uint8_t m_dataType
The ImageStreamIO type code.
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_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
float m_pupil_cx_1
the center x coordinate of pupil 1
INDI_SETCALLBACK_DECL(pwfsSlopeCalc, m_indiP_quad4)
virtual void setupConfig()
virtual int appStartup()
Startup function.
float m_pupil_cx_3
the center x coordinate of pupil 3
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.
virtual void loadConfig()
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_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.
mx::improc::eigenImage< realT > m_darkImage
int processImage(void *curr_src, const dev::shmimT &dummy)
#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
INDI_SETCALLBACK_DEFN(adcTracker, m_indiP_teldata)(const pcf
std::unique_lock< std::mutex > lock(m_indiMutex)
static std::string configSection()
static std::string indiPrefix()
A device base class which saves telemetry.
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.
Log entry recording framegrabber timings.