10#include "../../libMagAOX/libMagAOX.hpp"
11#include "../../magaox_git_version.h"
13#include <mx/math/gslInterpolation.hpp>
14#include <mx/ioutils/readColumns.hpp>
96 mx::app::appConfigurator &
_config );
181 config.add(
"hwp.zero",
189 "The HWP zero position. Default is 360." );
191 config.add(
"hwp.sign",
199 "The HWP rotation sign. Default is -1." );
201 config.add(
"hwp.devName",
209 "The device name of the HWPstage. Default is 'stagepolrot'" );
211 config.add(
"tcs.devName",
219 "The device name of the TCS Interface providing 'teldata.zd' and `teldata.pa`. Default is 'tcsi'" );
221 config.add(
"tracking.updateInterval",
223 "tracking.updateInterval",
229 "The interval at which to update positions, in seconds. Default is 1 sec." );
232 config.add(
"tracking.pupilOffset",
234 "tracking.pupilOffset",
240 "The HWP tracking pupil offset. Must match twice the kTracker offset. Default is 0." );
278 m_indiP_hwpSetPos,
"hwp_position", -360.0, 360.0, 1
e-3,
"%.03f",
"HWP Set Position",
"HWP Status" );
367 std::cerr <<
"Sending HWP stage to: " <<
hwpStagePos <<
"\n";
381 if(
ipRecv.getName() != m_indiP_hwpSetPos.getName() )
383 log<software_error>( { __FILE__, __LINE__,
"wrong INDI property received." } );
387 if( !
ipRecv.find(
"target" ) )
390 m_hwpSetPos =
ipRecv[
"target"].get<
float>();
392 updateIfChanged<float>(m_indiP_hwpSetPos,
"target", m_hwpSetPos);
404 if(
ipRecv.getName() != m_indiP_tracking.getName() )
406 log<software_error>( { __FILE__, __LINE__,
"wrong INDI property received." } );
410 if( !
ipRecv.find(
"toggle" ) )
415 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::On )
417 updateSwitchIfChanged( m_indiP_tracking,
"toggle", pcf::IndiElement::On,
INDI_IDLE );
421 getHwpTrackingOffset();
423 updateIfChanged<float>( m_indiP_hwpTrackingOffset,
"value", m_hwpTrackingOffset );
427 log<text_log>(
"started HWP rotation tracking" );
431 updateSwitchIfChanged( m_indiP_tracking,
"toggle", pcf::IndiElement::Off,
INDI_IDLE );
435 m_hwpTrackingOffset = 0;
437 updateIfChanged<float>( m_indiP_hwpTrackingOffset,
"value", m_hwpTrackingOffset );
441 log<text_log>(
"stopped HWP rotation tracking" );
452 if(
ipRecv.getName() != m_indiP_teldata.getName() )
454 log<software_error>( { __FILE__, __LINE__,
"wrong INDI property received" } );
459 if( !
ipRecv.find(
"zd" ) )
462 if( !
ipRecv.find(
"pa" ) )
465 m_altitude = 90 -
ipRecv[
"zd"].get<
float>();
467 m_parang =
ipRecv[
"pa"].get<
float>();
477 if(
ipRecv.getName() != m_indiP_stagePolRot.getName() )
479 log<software_error>( { __FILE__, __LINE__,
"wrong INDI property received" } );
484 if( !
ipRecv.find(
"current" ) )
487 float hwpStagePos =
ipRecv[
"current"].get<
float>();
489 m_hwpActualPos = m_sign * (hwpStagePos - m_zero);
490 if (fabs(m_hwpActualPos) < 1e-2)
492 updateIfChanged<float>(m_indiP_hwpActualPos,
"value", m_hwpActualPos);
494 m_hwpCurPos = m_hwpActualPos - m_hwpTrackingOffset;
496 m_hwpCurPos = std::round(m_hwpCurPos * 100) / 100;
497 updateIfChanged<float>(m_indiP_hwpSetPos,
"current", m_hwpCurPos);
499 m_hwpPosName = getHwpStatus();
501 updateIfChanged<std::string>( m_indiP_hwpPosName,
"value", m_hwpPosName );
513 if(
ipRecv.getName() != m_indiP_stagePolRotFsm.getName() )
515 log<software_error>( { __FILE__, __LINE__,
"wrong INDI property received" } );
520 if( !
ipRecv.find(
"state" ) )
523 std::string stagepolrot_state =
ipRecv[
"state"].get<std::string>();
548 static bool tracking =
false;
The base-class for XWCTk applications.
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 createStandardIndiToggleSw(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 toggle element.
static int log(const typename logT::messageT &msg, logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry.
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)
virtual int appLogic()
Implementation of the FSM for hwpTracker.
virtual void loadConfig()
virtual void updateHwpPos()
pcf::IndiProperty m_indiP_hwpPosName
int recordPolTrack(bool force=false)
virtual int appShutdown()
Shutdown the app.
INDI_SETCALLBACK_DECL(hwpTracker, m_indiP_stagePolRot)
~hwpTracker() noexcept
D'tor, declared and defined for noexcept.
pcf::IndiProperty m_indiP_hwpTrackingOffset
float m_hwpTrackingOffset
HWP tracking offset.
hwpTracker()
Default c'tor.
INDI_NEWCALLBACK_DECL(hwpTracker, m_indiP_hwpSetPos)
virtual void getHwpTrackingOffset()
pcf::IndiProperty m_indiP_tracking
dev::telemeter< hwpTracker > telemeterT
pcf::IndiProperty m_indiP_stagePolRot
std::string m_tcsDevName
The device name of the TCS Interface providing 'teldata.altitude'. Default is 'tcsi'.
INDI_SETCALLBACK_DECL(hwpTracker, m_indiP_teldata)
friend class hwpTracker_test
pcf::IndiProperty m_indiP_hwpActualPos
float m_altitude
Current altitude.
pcf::IndiProperty m_indiP_teldata
pcf::IndiProperty m_indiP_hwpStagePos
int m_sign
The sign to apply to the calculated HWP angle.
bool m_tracking
Is the HWP in ADI synchronization mode?. Default is false.
INDI_NEWCALLBACK_DECL(hwpTracker, m_indiP_tracking)
virtual int appStartup()
Startup function.
pcf::IndiProperty m_indiP_stagePolRotFsm
int recordTelem(const telem_poltrack *)
int loadConfigImpl(mx::app::appConfigurator &_config)
Implementation of loadConfig logic, separated for testing.
virtual std::string getHwpStatus()
float m_pupilOffset
The pupil offset used for HWP tracking (must match twice the kTracker offset)
float m_updateInterval
The interval at which to update positions, in seconds. Default is 10 secs.
virtual void setupConfig()
float m_parang
Current parallactic angle.
pcf::IndiProperty m_indiP_hwpSetPos
float m_zero
The zero point of the HWP stage.
INDI_SETCALLBACK_DECL(hwpTracker, m_indiP_stagePolRotFsm)
std::string m_devName
The device name of the HWP stage. Default is 'stagehwprot'.
#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_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.
@ READY
The device is ready for operation, but is not operating.
#define INDI_VALIDATE_CALLBACK_PROPS(prop1, prop2)
Standard check for matching INDI properties in a callback.
const pcf::IndiProperty & ipRecv
A device base class which saves telemetry.
int checkRecordTimes(const telT &tel, telTs... tels)
Check the time of the last record for each telemetry type and make an entry if needed.
static stateCodeT str2CodeFast(const std::string &stateStr)
Get the stateCode corresponding to an ASCII string with minimal checks.
Log entry recording poltrack stage specific status.
#define TELEMETER_APP_LOGIC
Call telemeter::appLogic with error checking.
#define TELEMETER_LOAD_CONFIG(cfig)
Call telemeter::loadConfig with error checking.
#define TELEMETER_APP_STARTUP
Call telemeter::appStartup with error checking.
#define TELEMETER_SETUP_CONFIG(cfig)
Call telemeter::setupConfig with error checking.
#define TELEMETER_APP_SHUTDOWN
Call telemeter::appShutdown with error checking.