19#include <mx/improc/eigenCube.hpp>
20#include <mx/improc/eigenImage.hpp>
21using namespace mx::improc;
23#include "../../libMagAOX/libMagAOX.hpp"
24#include "../../magaox_git_version.h"
145 mx::app::appConfigurator &
_config );
206 config.add(
"outputShmim.shmimName",
"",
"outputShmim.shmimName", argType::Required,
"outputShmim",
"shmimName",
false,
"string",
"The output shmim to write to.");
208 config.add(
"parameters.gain",
"",
"parameters.gain", argType::Required,
"parameters",
"gain",
false,
"float",
"The initial feedback gain.");
209 config.add(
"parameters.regularization",
"",
"parameters.regularization", argType::Required,
"parameters",
"regularization",
false,
"float",
"The regularization parameter.");
210 config.add(
"parameters.gamma",
"",
"parameters.gamma", argType::Required,
"parameters",
"gamma",
false,
"float",
"The forgetting factor.");
211 config.add(
"parameters.covariance",
"",
"parameters.covariance", argType::Required,
"parameters",
"covariance",
false,
"float",
"The initial covariance.");
213 config.add(
"parameters.num_modes",
"",
"parameters.num_modes", argType::Required,
"parameters",
"num_modes",
false,
"int",
"The number of modes that will be controlled through predictive control.");
214 config.add(
"parameters.history",
"",
"parameters.history", argType::Required,
"parameters",
"history",
false,
"int",
"The number of past measurements for the prediction.");
215 config.add(
"parameters.future",
"",
"parameters.future", argType::Required,
"parameters",
"future",
false,
"int",
"The number of future steps that are predicted.");
233 std::cout <<
"Open output channel at " <<
m_outputName << std::endl;
234 std::cout <<
"Gain " <<
m_gainCtrl << std::endl;
238 std::cout <<
"History " <<
m_history << std::endl;
239 std::cout <<
"Future " <<
m_future << std::endl;
241 std::cout <<
"Done reading config Impl." << std::endl;
317 static_cast<void>(
dummy );
329 generator = std::default_random_engine();
330 distribution = std::normal_distribution<DDSPC::realT>(0.0, 1.0);
458 std::cout <<
"HOWDY" << std::endl;
472 std::unique_lock<std::mutex>
lock( m_indiMutex );
474 if( indiTargetUpdate( m_indiP_exploration, target,
ipRecv,
true ) < 0 )
476 log<software_error>( { __FILE__, __LINE__ } );
481 m_exploration_sequence = target;
482 std::cout << target << std::endl;
484 std::stringstream csvStringStream(m_exploration_sequence);
488 while (getline(csvStringStream, entry,
',')){
492 m_exploration_steps_02.push_back(std::stoi(entry));
494 m_exploration_steps_01.push_back(std::stoi(entry));
496 }
else if(k % 3 == 1){
499 m_exploration_noise_strength_02.push_back(std::stod(entry));
501 m_exploration_noise_strength_01.push_back(std::stod(entry));
505 m_regularization_steps_02.push_back(std::stof(entry));
507 m_regularization_steps_01.push_back(std::stof(entry));
512 switch_exploration =
true;
519 if(
ipRecv.getName() != m_indiP_learningToggle.getName())
521 log<software_error>({__FILE__, __LINE__,
"invalid indi property received"});
526 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::On)
532 updateSwitchIfChanged(m_indiP_learningToggle,
"toggle", pcf::IndiElement::On,
INDI_BUSY);
538 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::Off)
544 updateSwitchIfChanged(m_indiP_learningToggle,
"toggle", pcf::IndiElement::Off,
INDI_IDLE);
554 if(
ipRecv.getName() != m_indiP_predictingToggle.getName())
556 log<software_error>({__FILE__, __LINE__,
"invalid indi property received"});
561 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::On)
563 if(!is_predictive_control)
565 is_predictive_control =
true;
567 updateSwitchIfChanged(m_indiP_predictingToggle,
"toggle", pcf::IndiElement::On,
INDI_BUSY);
574 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::Off)
576 if(is_predictive_control)
578 is_predictive_control =
false;
580 updateSwitchIfChanged(m_indiP_predictingToggle,
"toggle", pcf::IndiElement::Off,
INDI_IDLE);
591 if(
ipRecv.getName() != m_indiP_resetToggle.getName())
593 log<software_error>({__FILE__, __LINE__,
"invalid indi property received"});
597 if(!
ipRecv.find(
"request"))
return 0;
599 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
601 std::lock_guard<std::mutex> guard(m_indiMutex);
604 do_reset_model =
true;
606 updateSwitchIfChanged(m_indiP_resetToggle,
"request", pcf::IndiElement::Off,
INDI_IDLE);
void set_regularization(realT new_regularization)
Matrix calculate_command(Matrix new_measurement, Matrix exploration_noise)
The base-class for XWCTk applications.
int createStandardIndiRequestSw(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 request element.
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 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.
int loadConfig(mx::app::appConfigurator &config)
load the configuration system results
float m_regularizationCtrl
INDI_NEWCALLBACK_DECL(loPredCtrl, m_indiP_resetToggle)
friend class loPredCtrl_test
pcf::IndiProperty m_indiP_exploration
DDSPC::PredictiveController * controller
INDI_NEWCALLBACK_DECL(loPredCtrl, m_indiP_learningToggle)
std::string m_exploration_sequence
std::vector< float > m_exploration_noise_strength_01
pcf::IndiProperty m_indiP_learningToggle
std::vector< float > m_regularization_steps_02
void load(std::string directory)
~loPredCtrl() noexcept
D'tor, declared and defined for noexcept.
float realT
Floating point type in which to do all calculations.
loPredCtrl()
Default c'tor.
size_t m_outputTypeSize
The size of the type, in bytes.
uint8_t m_outputDataType
The ImageStreamIO type code.
INDI_NEWCALLBACK_DECL(loPredCtrl, m_indiP_exploration)
std::vector< float > m_regularization_steps_01
virtual int appLogic()
Implementation of the FSM for loPredCtrl.
DDSPC::Matrix new_command
std::normal_distribution< DDSPC::realT > distribution
pcf::IndiProperty m_indiP_predictingToggle
int processImage(void *curr_src, const dev::shmimT &dummy)
virtual void loadConfig()
dev::shmimMonitor< loPredCtrl > shmimMonitorT
void save(std::string directory)
std::vector< float > m_exploration_noise_strength_02
uint32_t m_modevalTypeSize
std::default_random_engine generator
int loadConfigImpl(mx::app::appConfigurator &_config)
Implementation of loadConfig logic, separated for testing.
uint32_t m_modevalWidth
The width of the shmim.
virtual int appShutdown()
Shutdown the app.
INDI_NEWCALLBACK_DECL(loPredCtrl, m_indiP_predictingToggle)
virtual void setupConfig()
uint32_t m_modevalHeight
The height of the shmim.
virtual int appStartup()
Startup function.
std::vector< int > m_exploration_steps_01
uint32_t m_outputWidth
The width of the image.
DDSPC::Matrix new_measurement
uint32_t m_outputHeight
The height of the image.
int allocate(const dev::shmimT &dummy)
std::vector< int > m_exploration_steps_02
bool is_predictive_control
pcf::IndiProperty m_indiP_resetToggle
DDSPC::Matrix full_command
#define INDI_NEWCALLBACK_DEFN(class, prop)
Define the callback for a new property request.
#define INDI_NEWCALLBACK(prop)
Get the name of the static callback wrapper for a new property.
#define CREATE_REG_INDI_NEW_TEXT(prop, name, label, group)
Create and register a NEW INDI property as a standard text, using the standard callback name.
@ OPERATING
The device is operating, other than homing.
#define INDI_VALIDATE_CALLBACK_PROPS(prop1, prop2)
Standard check for matching INDI properties in a callback.
Eigen::Matrix< realT, Eigen::Dynamic, Eigen::Dynamic > Matrix
const pcf::IndiProperty & ipRecv
std::unique_lock< std::mutex > lock(m_indiMutex)
static constexpr logPrioT LOG_NOTICE
A normal but significant condition.