11 #include "../../libMagAOX/libMagAOX.hpp"
12 #include "../../magaox_git_version.h"
14 #include <mx/math/gslInterpolator.hpp>
15 #include <mx/ioutils/readColumns.hpp>
87 mx::math::gslInterpolator<mx::math::gsl_interp_linear<double>>
m_terpADC1;
88 mx::math::gslInterpolator<mx::math::gsl_interp_linear<double>>
m_terpADC2;
176 config.add(
"adcs.lookupFile",
"",
"adcs.lookupFile", argType::Required,
"adcs",
"lookupFile",
false,
"string",
"The name of the file, in the calib directory, containing the adc lookup table. Default is 'adc_lookup_table.txt'.");
178 config.add(
"adcs.adc1zero",
"",
"adcs.adc1zero", argType::Required,
"adcs",
"adc1zero",
false,
"float",
"The starting point for ADC 1. Default is 0.");
180 config.add(
"adcs.adc1lupsign",
"",
"adcs.adc1lupsign", argType::Required,
"adcs",
"adc1lupsign",
false,
"int",
"The sign to apply for the LUP values for ADC 1. Default is +1.");
182 config.add(
"adcs.adc2zero",
"",
"adcs.adc2zero", argType::Required,
"adcs",
"adc2zero",
false,
"float",
"The starting point for ADC 2. Default is 0.");
184 config.add(
"adcs.adc2lupsign",
"",
"adcs.adc2lupsign", argType::Required,
"adcs",
"adc2lupsign",
false,
"int",
"The sign to apply for the LUP values for ADC 2. Default is +1.");
186 config.add(
"adcs.deltaAngle",
"",
"adcs.deltaAngle", argType::Required,
"adcs",
"deltaAngle",
false,
"float",
"The offset angle to apply to the looked-up values, applied to both. Default is 0.");
188 config.add(
"adcs.adc1delta",
"",
"adcs.adc1delta", argType::Required,
"adcs",
"adc1delta",
false,
"float",
"The offset angle to apply to the looked-up value for ADC 1, applied in addition to deltaAngle. Default is 0.");
190 config.add(
"adcs.adc2delta",
"",
"adcs.adc2delta", argType::Required,
"adcs",
"adc2delta",
false,
"float",
"The offset angle to apply to the looked-up value for ADC 2, applied in addition to deltaAngle. Default is 0.");
192 config.add(
"adcs.minZD",
"",
"adcs.minZD", argType::Required,
"adcs",
"minZD",
false,
"float",
"The minimum zenith distance at which to interpolate and move the ADCs. Default is 5.1");
194 config.add(
"adcs.adc1DevName",
"",
"adcs.adc1devName", argType::Required,
"adcs",
"adc1DevName",
false,
"string",
"The device name of the ADC 1 stage. Default is 'stageadc1'");
196 config.add(
"adcs.adc2DevName",
"",
"adcs.adc2devName", argType::Required,
"adcs",
"adc2DevName",
false,
"string",
"The device name of the ADC 2 stage. Default is 'stageadc2'");
198 config.add(
"tcs.devName",
"",
"tcs.devName", argType::Required,
"tcs",
"devName",
false,
"string",
"The device name of the TCS Interface providing 'teldata.zd'. Default is 'tcsi'");
200 config.add(
"tracking.updateInterval",
"",
"tracking.updateInterval", argType::Required,
"tracking",
"updateInterval",
false,
"float",
"The interval at which to update positions, in seconds. Default is 10 secs.");
213 _config(
m_minZD,
"adcs.minZD");
234 std::cerr <<
"Reading " << luppath <<
"\n";
238 log<software_critical>({__FILE__,__LINE__,
"error reading lookup table from " + luppath});
244 log<software_critical>({__FILE__,__LINE__,
"inconsistent sizes in " + luppath});
256 createStandardIndiNumber<float>(
m_indiP_deltaAngle,
"deltaAngle", 0.0, 180.0, 0,
"%0.2f");
261 createStandardIndiNumber<float>(
m_indiP_deltaADC1,
"deltaADC1", 0.0, 180.0, 0,
"%0.2f");
266 createStandardIndiNumber<float>(
m_indiP_deltaADC2,
"deltaADC2", 0.0, 180.0, 0,
"%0.2f");
271 createStandardIndiNumber<float>(
m_indiP_minZD,
"minZD", 0.0, 90.0, 0,
"%0.2f");
296 static double lastupdate = 0;
322 std::cerr <<
"Sending adcs to: " << adc1 <<
" " << adc2 <<
"\n";
331 lastupdate = mx::sys::get_curr_time();
347 if(!
ipRecv.find(
"toggle"))
return 0;
349 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::On)
355 log<text_log>(
"started ADC rotation tracking");
363 log<text_log>(
"stopped ADC rotation tracking");
375 if( indiTargetUpdate( m_indiP_deltaAngle, target,
ipRecv) < 0)
377 log<software_error>({__FILE__,__LINE__});
381 m_deltaAngle = target;
383 std::lock_guard<std::mutex> guard(m_indiMutex);
387 log<text_log>(
"set deltaAngle to " + std::to_string(m_deltaAngle));
398 if( indiTargetUpdate( m_indiP_deltaADC1, target,
ipRecv) < 0)
400 log<software_error>({__FILE__,__LINE__});
404 m_adc1delta = target;
406 std::lock_guard<std::mutex> guard(m_indiMutex);
410 log<text_log>(
"set deltaADC1 to " + std::to_string(m_adc1delta));
421 if( indiTargetUpdate( m_indiP_deltaADC2, target,
ipRecv) < 0)
423 log<software_error>({__FILE__,__LINE__});
427 m_adc2delta = target;
429 std::lock_guard<std::mutex> guard(m_indiMutex);
433 log<text_log>(
"set deltaADC2 to " + std::to_string(m_adc2delta));
444 if( indiTargetUpdate( m_indiP_minZD, target,
ipRecv) < 0)
446 log<software_error>({__FILE__,__LINE__});
452 std::lock_guard<std::mutex> guard(m_indiMutex);
456 log<text_log>(
"set minZD to " + std::to_string(m_minZD));
466 if(!
ipRecv.find(
"zd"))
return 0;
468 m_zd =
ipRecv[
"zd"].get<
float>();
The base-class for MagAO-X 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.
std::string m_calibDir
The path to calibration files for MagAOX.
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)
pcf::IndiProperty m_indiP_deltaADC1
std::string m_lookupFile
The name of the file, in the calib directory, containing the adc lookup table. Default is 'adc_lookup...
virtual int appShutdown()
Shutdown the app.
std::vector< double > m_lupZD
std::vector< double > m_lupADC1
int loadConfigImpl(mx::app::appConfigurator &_config)
Implementation of loadConfig logic, separated for testing.
float m_deltaAngle
The offset angle to apply to the looked-up values, applied to both. Default is 0.
float m_adc1delta
The offset angle to apply to the looked-up value for ADC 1, applied in addition to deltaAngle....
pcf::IndiProperty m_indiP_deltaADC2
pcf::IndiProperty m_indiP_teldata
INDI_NEWCALLBACK_DECL(adcTracker, m_indiP_tracking)
INDI_NEWCALLBACK_DECL(adcTracker, m_indiP_deltaADC2)
~adcTracker() noexcept
D'tor, declared and defined for noexcept.
std::string m_adc2DevName
The device name of the ADC 2 stage. Default is 'stageadc2'.
INDI_SETCALLBACK_DECL(adcTracker, m_indiP_teldata)
pcf::IndiProperty m_indiP_tracking
mx::math::gslInterpolator< mx::math::gsl_interp_linear< double > > m_terpADC1
pcf::IndiProperty m_indiP_deltaAngle
std::string m_adc1DevName
The device name of the ADC 1 stage. Default is 'stageadc1'.
pcf::IndiProperty m_indiP_adc2pos
INDI_NEWCALLBACK_DECL(adcTracker, m_indiP_deltaAngle)
friend class adcTracker_test
virtual void setupConfig()
pcf::IndiProperty m_indiP_minZD
std::string m_tcsDevName
The device name of the TCS Interface providing 'teldata.zd'. Default is 'tcsi'.
float m_adc2delta
The offset angle to apply to the looked-up value for ADC 2, applied in addition to deltaAngle....
mx::math::gslInterpolator< mx::math::gsl_interp_linear< double > > m_terpADC2
float m_adc1zero
The starting point for ADC 1. Default is 0.
adcTracker()
Default c'tor.
virtual int appStartup()
Startup function.
int m_adc1lupsign
The sign to apply to the lookup table value for ADC 1.
float m_adc2zero
The starting point for ADC 2. Default is 0.
pcf::IndiProperty m_indiP_adc1pos
INDI_NEWCALLBACK_DECL(adcTracker, m_indiP_minZD)
int m_adc2lupsign
The sign to apply to the lookup table value for ADC 2.
std::vector< double > m_lupADC2
virtual int appLogic()
Implementation of the FSM for adcTracker.
float m_minZD
"The minimum zenith distance at which to interpolate and move the ADCs. Default is 0.
INDI_NEWCALLBACK_DECL(adcTracker, m_indiP_deltaADC1)
virtual void loadConfig()
#define INDI_NEWCALLBACK(prop)
Get the name of the static callback wrapper for a new property.
#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.
void updateSwitchIfChanged(pcf::IndiProperty &p, const std::string &el, const pcf::IndiElement::SwitchStateType &newVal, indiDriverT *indiDriver, pcf::IndiProperty::PropertyStateType newState=pcf::IndiProperty::Ok)
Update the value of the INDI element, but only if it has changed.
INDI_VALIDATE_CALLBACK_PROPS(function, ipRecv)
const pcf::IndiProperty & ipRecv
INDI_SETCALLBACK_DEFN(adcTracker, m_indiP_teldata)(const pcf
updateIfChanged(m_indiP_angle, "target", m_angle)
INDI_NEWCALLBACK_DEFN(acesxeCtrl, m_indiP_windspeed)(const pcf