11 #include "../../libMagAOX/libMagAOX.hpp"
12 #include "../../magaox_git_version.h"
167 config.add(
"ctrl.devices",
"",
"ctrl.devices", argType::Required,
"ctrl",
"devices",
false,
"string",
"Device names of the controller(s) (one per element).");
168 config.add(
"ctrl.properties",
"",
"ctrl.properties", argType::Required,
"ctrl",
"properties",
false,
"string",
"Properties of the ctrl devices to which to give the commands. One per element");
169 config.add(
"ctrl.currents",
"",
"ctrl.currents", argType::Required,
"ctrl",
"currents",
false,
"vector<string>",
"current elements of the properties on which base the commands.");
170 config.add(
"ctrl.targets",
"",
"ctrl.targets", argType::Required,
"ctrl",
"targets",
false,
"vector<string>",
"target elements of the properties to which to send the commands.");
172 config.add(
"loop.gain",
"",
"loop.gain", argType::Required,
"loop",
"gain",
false,
"float",
"default global loop gain.");
173 config.add(
"loop.intMat",
"",
"loop.intMat", argType::Required,
"loop",
"intMat",
false,
"string",
"file name of the interaction matrix.");
174 config.add(
"loop.gains",
"",
"loop.gains", argType::Required,
"loop",
"gains",
false,
"vector<float>",
"default loop gains. If single number, it is applied to all axes.");
175 config.add(
"loop.upstream",
"",
"loop.upstream", argType::Required,
"loop",
"upstream",
false,
"string",
"Upstream loop device name. This loop will open, and optionally close, with the upstream loop. Default none.");
176 config.add(
"loop.upstreamProperty",
"",
"loop.upstreamProperty", argType::Required,
"loop",
"upstreamProperty",
false,
"string",
"Property of upstream loop device to follow. Must be a toggle. Default is loop_state.");
210 return log<
software_error, -1>({__FILE__, __LINE__,
"ctrl.Targets and ctrl.devices are not the same size"});
215 return log<
software_error, -1>({__FILE__, __LINE__,
"ctrl.Targets and ctrl.properties are not the same size"});
220 return log<
software_error, -1>({__FILE__, __LINE__,
"ctrl.Currents and ctrl.properties are not the same size"});
229 log<text_log>(
"Setting loop.gains gains to be same size as ctrl.Targets",
logPrio::LOG_NOTICE);
233 return log<
software_error, -1>({__FILE__, __LINE__,
"ctrl.Targets and loop.gains are not the same size"});
246 createStandardIndiNumber<unsigned>(
m_indiP_ggain,
"loop_gain", 0, 1, 0,
"%0.2f");
251 log<software_error>({__FILE__,__LINE__});
258 log<software_error>({__FILE__,__LINE__});
358 static_cast<void>(dummy);
373 static_cast<void>(dummy);
404 std::vector<float> commands;
435 pcf::IndiProperty ip(pcf::IndiProperty::Number);
450 if(
ipRecv.getName() != m_indiP_ggain.getName())
452 log<software_error>({__FILE__, __LINE__,
"invalid indi property received"});
458 if( indiTargetUpdate( m_indiP_ggain, target,
ipRecv,
true) < 0)
460 log<software_error>({__FILE__,__LINE__});
476 if(
ipRecv.getName() != m_indiP_ctrlEnabled.getName())
478 log<software_error>({__FILE__, __LINE__,
"invalid indi property received"});
483 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::On)
485 return toggleLoop(
true);
489 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::Off)
491 return toggleLoop(
false);
516 if(
ipRecv.getName() != m_indiP_upstream.getName())
518 return log<software_error>({__FILE__,__LINE__,
"wrong INDI property received"});
521 if(!
ipRecv.find(
"toggle"))
return 0;
523 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::On && m_upstreamFollowClosed)
526 return toggleLoop(
true);
528 else if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::Off)
531 return toggleLoop(
false);
The base-class for MagAO-X 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.
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.
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::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)
int registerIndiPropertySet(pcf::IndiProperty &prop, const std::string &devName, const std::string &propName, int(*)(void *, const pcf::IndiProperty &))
Register an INDI property which is monitored for updates from others.
int processImage(void *curr_src, const dev::shmimT &)
pcf::IndiProperty m_indiP_ctrlEnabled
bool m_upstreamFollowClosed
std::vector< std::string > m_ctrlProperties
mx::improc::eigenImage< float > m_commands
static int st_setCallBack_ctrl(void *app, const pcf::IndiProperty &ipRecv)
int toggleLoop(bool onoff)
std::vector< float > m_gains
virtual int appStartup()
Startup function.
INDI_NEWCALLBACK_DECL(alignLoop, m_indiP_ctrlEnabled)
std::vector< std::string > m_ctrlCurrents
std::vector< std::string > m_ctrlTargets
INDI_SETCALLBACK_DECL(alignLoop, m_indiP_upstream)
pcf::IndiProperty m_indiP_deltas
int allocate(const dev::shmimT &)
dev::shmimMonitor< alignLoop > shmimMonitorT
mx::improc::eigenImage< float > m_intMat
std::vector< std::string > m_ctrlDevices
std::string m_upstreamDevice
std::vector< float > m_defaultGains
virtual int appLogic()
Implementation of the FSM for alignLoop.
std::string m_upstreamProperty
int setCallBack_ctrl(const pcf::IndiProperty &ipRecv)
virtual int appShutdown()
Shutdown the app.
pcf::IndiProperty m_indiP_ggain
std::vector< float > m_currents
~alignLoop() noexcept
D'tor, declared and defined for noexcept.
alignLoop()
Default c'tor.
friend class alignLoop_test
INDI_NEWCALLBACK_DECL(alignLoop, m_indiP_ggain)
std::vector< pcf::IndiProperty > m_indiP_ctrl
int loadConfigImpl(mx::app::appConfigurator &_config)
Implementation of loadConfig logic, separated for testing.
mx::improc::eigenImage< float > m_measurements
pcf::IndiProperty m_indiP_upstream
Property used to report the loop state.
virtual void setupConfig()
int sendCommands(std::vector< float > &commands)
virtual void loadConfig()
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 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
#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.
#define CREATE_REG_INDI_RO_NUMBER(prop, name, label, group)
Create and register a RO INDI property as a number, 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
updateIfChanged(m_indiP_angle, "target", m_angle)
INDI_NEWCALLBACK_DEFN(acesxeCtrl, m_indiP_windspeed)(const pcf
constexpr static logPrioT LOG_NOTICE
A normal but significant condition.