16 #include <mx/improc/eigenCube.hpp>
17 #include <mx/improc/eigenImage.hpp>
18 using namespace mx::improc;
20 #include "../../libMagAOX/libMagAOX.hpp"
21 #include "../../magaox_git_version.h"
23 #include "predictive_controller.cuh"
25 using namespace DDSPC;
67 friend class hoPredCtrl_test;
104 size_t m_pwfsWidth {0};
105 size_t m_pwfsHeight {0};
107 size_t m_quadWidth {0};
108 size_t m_quadHeight {0};
110 uint8_t m_pwfsDataType{0};
111 size_t m_pwfsTypeSize {0};
131 realT (*pwfs_pixget)(
void *, size_t) {
nullptr};
135 realT (*dark_pixget)(
void *, size_t) {
nullptr};
136 bool m_darkSet {
false};
177 uint32_t m_dmWidth {0};
178 uint32_t m_dmHeight {0};
180 uint8_t m_dmDataType{0};
181 size_t m_dmTypeSize {0};
183 bool m_dmOpened {
false};
184 bool m_dmRestart {
false};
263 virtual void setupConfig();
268 int loadConfigImpl( mx::app::appConfigurator & _config );
270 virtual void loadConfig();
276 virtual int appStartup();
283 virtual int appLogic();
289 virtual int appShutdown();
292 int processImage(
void * curr_src,
298 int processImage(
void * curr_src,
303 int send_dm_command();
304 int map_command_vector_to_dmshmim();
305 int set_pupil_mask(std::string pupil_mask_filename);
315 hoPredCtrl::hoPredCtrl() :
MagAOXApp(MAGAOX_CURRENT_SHA1, MAGAOX_REPO_MODIFIED)
327 config.add(
"parameters.calib_directory",
"",
"parameters.calib_directory", argType::Required,
"parameters",
"calib_directory",
false,
"string",
"The path to the PyWFS pupil mask.");
328 config.add(
"parameters.pupil_mask",
"",
"parameters.pupil_mask", argType::Required,
"parameters",
"pupil_mask",
false,
"string",
"The path to the PyWFS pupil mask.");
329 config.add(
"parameters.interaction_matrix",
"",
"parameters.interaction_matrix", argType::Required,
"parameters",
"interaction_matrix",
false,
"string",
"The path to the PyWFS interaction matrix.");
330 config.add(
"parameters.mapping_matrix",
"",
"parameters.mapping_matrix", argType::Required,
"parameters",
"mapping_matrix",
false,
"string",
"The path to the DM mapping matrix.");
331 config.add(
"parameters.act_mask",
"",
"parameters.act_mask", argType::Required,
"parameters",
"act_mask",
false,
"string",
"The path to the PyWFS interaction matrix.");
332 config.add(
"parameters.reference_image",
"",
"parameters.reference_image", argType::Required,
"parameters",
"reference_image",
false,
"string",
"The path to the PyWFS interaction matrix.");
335 config.add(
"parameters.Nhist",
"",
"parameters.Nhist", argType::Required,
"parameters",
"Nhist",
false,
"int",
"The history length.");
336 config.add(
"parameters.Nfut",
"",
"parameters.Nfut", argType::Required,
"parameters",
"Nfut",
false,
"int",
"The prediction horizon.");
337 config.add(
"parameters.gamma",
"",
"parameters.gamma", argType::Required,
"parameters",
"gamma",
false,
"float",
"The prediction horizon.");
338 config.add(
"parameters.inv_covariance",
"",
"parameters.inv_covariance", argType::Required,
"parameters",
"inv_covariance",
false,
"float",
"The prediction horizon.");
339 config.add(
"parameters.lambda",
"",
"parameters.lambda", argType::Required,
"parameters",
"lambda",
false,
"float",
"The prediction horizon.");
340 config.add(
"parameters.clip_val",
"",
"parameters.clip_val", argType::Required,
"parameters",
"clip_val",
false,
"float",
"The update clip value.");
343 config.add(
"parameters.learning_steps",
"",
"parameters.learning_steps", argType::Required,
"parameters",
"learning_steps",
false,
"int",
"The update clip value.");
344 config.add(
"parameters.learning_iterations",
"",
"parameters.learning_iterations", argType::Required,
"parameters",
"learning_iterations",
false,
"int",
"The amount of learning cycles.");
345 config.add(
"parameters.exploration_steps",
"",
"parameters.exploration_steps", argType::Required,
"parameters",
"exploration_steps",
false,
"int",
"The update clip value.");
346 config.add(
"parameters.exploration_rms",
"",
"parameters.exploration_rms", argType::Required,
"parameters",
"exploration_rms",
false,
"float",
"The update clip value.");
354 config.add(
"parameters.channel",
"",
"parameters.channel", argType::Required,
"parameters",
"channel",
false,
"string",
"The DM channel to control.");
357 config.add(
"integrator.gain",
"",
"integrator.gain", argType::Required,
"integrator",
"gain",
false,
"float",
"The integrator gain value.");
358 config.add(
"integrator.leakage",
"",
"integrator.leakage", argType::Required,
"integrator",
"leakage",
false,
"float",
"The integrator leakage.");
370 _config(
m_intleak,
"integrator.leakage");
373 std::string calibration_directory;
374 _config(calibration_directory,
"parameters.calib_directory");
395 _config(
m_numFut,
"parameters.Nfut");
398 _config(
m_gamma,
"parameters.gamma");
402 _config(
m_lambda,
"parameters.lambda");
418 std::cout <<
"Done reading config Impl." << std::endl;
470 createStandardIndiNumber<uint64_t>(
m_indiP_timestamp,
"timestamp", -1, 20000000000000000, 1,
"%d",
"Timestamp",
"Loading the controller");
473 createStandardIndiNumber<int>(
m_indiP_learningSteps,
"learning_steps", -1, 200000, 1,
"%d",
"Learning Steps",
"Learning control");
476 createStandardIndiNumber<int>(
m_indiP_learningSteps,
"learning_steps", -1, 200000, 1,
"%d",
"Learning Steps",
"Learning control");
479 createStandardIndiNumber<int>(
m_indiP_learningIterations,
"learning_iterations", -1, 200000, 1,
"%d",
"Learning iterations",
"Learning control");
482 createStandardIndiNumber<float>(
m_indiP_explorationRms,
"exploration_rms", 0.0, 1.0, 0.00001,
"%0.4f",
"Learning Steps",
"Learning control");
485 createStandardIndiNumber<float>(
m_indiP_explorationSteps,
"exploration_steps", 0, 200000, 1,
"%d",
"Exploration Steps",
"Learning control");
488 createStandardIndiNumber<float>(
m_indiP_gamma,
"gamma", 0, 1.0, 0.0001,
"%0.3f",
"Forgetting parameter",
"Learning control");
491 createStandardIndiNumber<float>(
m_indiP_lambda,
"lambda", 0, 1000.0, 0.0001,
"%0.3f",
"Regularization",
"Learning control");
494 createStandardIndiNumber<float>(
m_indiP_clipval,
"clipval", 0, 1000.0, 0.0001,
"%0.3f",
"Regularization",
"Learning control");
503 createStandardIndiNumber<float>(
m_indiP_intgain,
"intgain", 0, 1.0, 0.0001,
"%0.3f",
"Integrator gain",
"Learning control");
506 createStandardIndiNumber<float>(
m_indiP_intleak,
"intleak", 0, 1.0, 0.0001,
"%0.3f",
"Integrator gain",
"Learning control");
532 log<software_error>({__FILE__, __LINE__});
537 log<software_error>({__FILE__, __LINE__});
591 static_cast<void>(dummy);
606 std::cout <<
"Start reading in calibration files\n";
609 mx::fits::fitsFile<realT> ff;
610 eigenCube<realT> temp_matrix;
615 std::cerr <<
"Read a " << temp_matrix.rows() <<
" x " << temp_matrix.cols() <<
" x " << temp_matrix.planes() <<
" interaction matrix.\n";
622 bool use_cacao_calib =
true;
635 std::cout <<
"Norm for mode " << row_i <<
" " << norm << std::endl;
647 realT test_norm = 0.0;
651 std::cout <<
"Test Norm for mode " << row_i <<
" " << test_norm << std::endl;
671 std::cerr <<
"Initialized temp command.\n";
713 std::cerr <<
"Finished intializing the controller.\n";
720 std::cerr <<
"Initialized exploration buffer.\n";
739 savepath =
"/data/users/xsup/PredCtrlData/";
747 static_cast<void>(dummy);
748 auto start = std::chrono::steady_clock::now();
750 Eigen::Map<eigenImage<unsigned short>> pwfsIm(
static_cast<unsigned short *
>(curr_src),
m_pwfsHeight,
m_pwfsWidth);
756 realT Ia = 0, Ib = 0, Ic = 0, Id = 0;
757 realT total_norm = 0;
758 size_t number_of_pixels = 0;
761 for(uint32_t col_i=0; col_i <
m_quadWidth; ++col_i){
771 pwfs_norm = Ia + Ib + Ic + Id;
779 total_norm += pwfs_norm;
788 for(uint32_t col_i=0; col_i <
m_pwfsWidth; ++col_i){
796 for(uint32_t col_i=0; col_i <
m_pwfsWidth; ++col_i){
854 auto end = std::chrono::steady_clock::now();
858 duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
860 duration = 0.95 *
duration + 0.05 * std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
882 mx::fits::fitsFile<realT> ff;
915 static_cast<void>(dummy);
925 log<software_error>({__FILE__, __LINE__,
"bad data type"});
928 std::cout <<
"Allocated dark frames stuff. \n";
940 static_cast<void>(dummy);
979 for(uint32_t col_i=0; col_i <
m_dmHeight; ++col_i){
980 for(uint32_t row_i=0; row_i <
m_dmHeight; ++row_i){
1008 if(
ipRecv.getName() != m_indiP_learningSteps.getName())
1010 log<software_error>({__FILE__,__LINE__,
"wrong INDI property received."});
1017 if(
ipRecv.find(
"current"))
1019 current =
ipRecv[
"current"].get<
int>();
1022 if(
ipRecv.find(
"target"))
1024 target =
ipRecv[
"target"].get<
int>();
1027 if(target == -1) target = current;
1034 std::lock_guard<std::mutex> guard(m_indiMutex);
1036 m_learning_counter = target;
1037 m_learning_steps = target;
1046 if(
ipRecv.getName() != m_indiP_learningIterations.getName())
1048 log<software_error>({__FILE__,__LINE__,
"wrong INDI property received."});
1055 if(
ipRecv.find(
"current"))
1057 current =
ipRecv[
"current"].get<
int>();
1060 if(
ipRecv.find(
"target"))
1062 target =
ipRecv[
"target"].get<
int>();
1065 if(target == -1) target = current;
1072 std::lock_guard<std::mutex> guard(m_indiMutex);
1074 m_learning_iterations = target;
1076 updateIfChanged(m_indiP_learningIterations,
"target", m_learning_iterations);
1083 if(
ipRecv.getName() != m_indiP_explorationRms.getName())
1085 log<software_error>({__FILE__,__LINE__,
"wrong INDI property received."});
1092 if(
ipRecv.find(
"current"))
1094 current =
ipRecv[
"current"].get<
float>();
1097 if(
ipRecv.find(
"target"))
1099 target =
ipRecv[
"target"].get<
float>();
1102 if(target == -1) target = current;
1109 std::lock_guard<std::mutex> guard(m_indiMutex);
1111 m_exploration_rms = target;
1112 std::cout <<
"New expl. rms: " << m_exploration_rms <<
"\n";
1121 if(
ipRecv.getName() != m_indiP_explorationSteps.getName())
1123 log<software_error>({__FILE__,__LINE__,
"wrong INDI property received."});
1130 if(
ipRecv.find(
"current"))
1132 current =
ipRecv[
"current"].get<
float>();
1135 if(
ipRecv.find(
"target"))
1137 target =
ipRecv[
"target"].get<
float>();
1140 if(target == -1) target = current;
1147 std::lock_guard<std::mutex> guard(m_indiMutex);
1149 m_exploration_steps = target;
1151 updateIfChanged(m_indiP_explorationSteps,
"target", m_exploration_steps);
1158 if(
ipRecv.getName() != m_indiP_lambda.getName()){
1159 log<software_error>({__FILE__,__LINE__,
"wrong INDI property received."});
1166 if(
ipRecv.find(
"current"))
1167 current =
ipRecv[
"current"].get<
float>();
1169 if(
ipRecv.find(
"target"))
1170 target =
ipRecv[
"target"].get<float>();
1172 if(target == -1) target = current;
1177 std::lock_guard<std::mutex> guard(m_indiMutex);
1178 if(!m_is_closed_loop){
1180 controller->set_new_regularization(m_lambda);
1191 if(
ipRecv.getName() != m_indiP_clipval.getName()){
1192 log<software_error>({__FILE__,__LINE__,
"wrong INDI property received."});
1199 if(
ipRecv.find(
"current"))
1200 current =
ipRecv[
"current"].get<
float>();
1202 if(
ipRecv.find(
"target"))
1203 target =
ipRecv[
"target"].get<float>();
1205 if(target == -1) target = current;
1210 std::lock_guard<std::mutex> guard(m_indiMutex);
1211 if(!m_is_closed_loop){
1212 m_clip_val = target;
1223 if(
ipRecv.getName() != m_indiP_gamma.getName()){
1224 log<software_error>({__FILE__,__LINE__,
"wrong INDI property received."});
1231 if(
ipRecv.find(
"current"))
1232 current =
ipRecv[
"current"].get<
float>();
1234 if(
ipRecv.find(
"target"))
1235 target =
ipRecv[
"target"].get<float>();
1237 if(target == -1) target = current;
1242 std::lock_guard<std::mutex> guard(m_indiMutex);
1244 if(!m_is_closed_loop){
1247 controller->set_new_gamma(m_gamma);
1258 if(
ipRecv.getName() != m_indiP_intgain.getName()){
1259 log<software_error>({__FILE__,__LINE__,
"wrong INDI property received."});
1266 if(
ipRecv.find(
"current"))
1267 current =
ipRecv[
"current"].get<
float>();
1269 if(
ipRecv.find(
"target"))
1270 target =
ipRecv[
"target"].get<float>();
1272 if(target == -1) target = current;
1277 std::lock_guard<std::mutex> guard(m_indiMutex);
1281 controller->controller->set_integrator(m_use_predictive_control, m_intgain, m_intleak);
1294 if(
ipRecv.getName() != m_indiP_intleak.getName()){
1295 log<software_error>({__FILE__,__LINE__,
"wrong INDI property received."});
1302 if(
ipRecv.find(
"current"))
1303 current =
ipRecv[
"current"].get<
float>();
1305 if(
ipRecv.find(
"target"))
1306 target =
ipRecv[
"target"].get<float>();
1308 if(target == -1) target = current;
1313 std::lock_guard<std::mutex> guard(m_indiMutex);
1317 controller->controller->set_integrator(m_use_predictive_control, m_intgain, m_intleak);
1331 if(
ipRecv.getName() != m_indiP_timestamp.getName()){
1332 log<software_error>({__FILE__,__LINE__,
"wrong INDI property received."});
1336 uint64_t current = -1;
1337 uint64_t target = -1;
1339 if(
ipRecv.find(
"current"))
1340 current =
ipRecv[
"current"].get<uint64_t>();
1342 if(
ipRecv.find(
"target"))
1343 target =
ipRecv[
"target"].get<uint64_t>();
1345 if(target == -1) target = current;
1350 std::lock_guard<std::mutex> guard(m_indiMutex);
1352 loading_timestamp = target;
1361 if(
ipRecv.getName() != m_indiP_controlToggle.getName())
1363 log<software_error>({__FILE__, __LINE__,
"invalid indi property received"});
1368 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::On)
1370 if(!m_is_closed_loop)
1375 m_is_closed_loop =
true;
1384 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::Off)
1386 if(m_is_closed_loop)
1388 m_is_closed_loop =
false;
1400 if(
ipRecv.getName() != m_indiP_predictorToggle.getName())
1402 log<software_error>({__FILE__, __LINE__,
"invalid indi property received"});
1407 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::On)
1409 m_use_predictive_control =
true;
1410 controller->controller->set_integrator(m_use_predictive_control, m_intgain, m_intleak);
1417 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::Off)
1419 if(!m_is_closed_loop)
1421 m_use_predictive_control =
false;
1422 controller->controller->set_integrator(m_use_predictive_control, m_intgain, m_intleak);
1434 if(
ipRecv.getName() != m_indiP_reset_bufferRequest.getName())
1436 log<software_error>({__FILE__, __LINE__,
"invalid indi property received"});
1440 if(!
ipRecv.find(
"request"))
return 0;
1442 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
1444 std::lock_guard<std::mutex> guard(m_indiMutex);
1445 controller->reset_data_buffer();
1455 if(
ipRecv.getName() != m_indiP_reset_exploreRequest.getName())
1457 log<software_error>({__FILE__, __LINE__,
"invalid indi property received"});
1461 if(!
ipRecv.find(
"request"))
return 0;
1463 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
1465 std::lock_guard<std::mutex> guard(m_indiMutex);
1466 controller->create_exploration_buffer(m_exploration_rms, m_exploration_steps);
1476 if(
ipRecv.getName() != m_indiP_reset_modelRequest.getName())
1478 log<software_error>({__FILE__, __LINE__,
"invalid indi property received"});
1482 if(!
ipRecv.find(
"request"))
return 0;
1484 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
1486 std::lock_guard<std::mutex> guard(m_indiMutex);
1487 controller->reset_controller();
1498 if(
ipRecv.getName() != m_indiP_reset_cleanRequest.getName())
1500 log<software_error>({__FILE__, __LINE__,
"invalid indi property received"});
1504 if(!
ipRecv.find(
"request"))
return 0;
1506 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
1508 std::lock_guard<std::mutex> guard(m_indiMutex);
1511 controller->create_exploration_buffer(m_exploration_rms, m_exploration_steps);
1514 controller->reset_controller();
1515 controller->reset_data_buffer();
1519 controller->set_zero();
1530 if(
ipRecv.getName() != m_indiP_updateControllerRequest.getName())
1532 log<software_error>({__FILE__, __LINE__,
"invalid indi property received"});
1536 if(!
ipRecv.find(
"request"))
return 0;
1538 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
1540 std::lock_guard<std::mutex> guard(m_indiMutex);
1543 controller->update_controller();
1553 if(
ipRecv.getName() != m_indiP_zeroRequest.getName())
1555 log<software_error>({__FILE__, __LINE__,
"invalid indi property received"});
1559 if(!
ipRecv.find(
"request"))
return 0;
1561 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
1564 if(!m_is_closed_loop){
1566 controller->set_zero();
1568 m_shaped_command.setZero();
1579 if(
ipRecv.getName() != m_indiP_saveRequest.getName())
1581 log<software_error>({__FILE__, __LINE__,
"invalid indi property received"});
1585 if(!
ipRecv.find(
"request"))
return 0;
1587 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
1589 controller->save_state(savepath);
1599 if(
ipRecv.getName() != m_indiP_loadRequest.getName())
1601 log<software_error>({__FILE__, __LINE__,
"invalid indi property received"});
1605 if(!
ipRecv.find(
"request"))
return 0;
1607 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
1609 controller->load_state(savepath, std::to_string(loading_timestamp));
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.
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.
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...
pcf::IndiProperty m_indiP_explorationSteps
INDI_NEWCALLBACK_DECL(hoPredCtrl, m_indiP_reset_exploreRequest)
pcf::IndiProperty m_indiP_zeroRequest
INDI_NEWCALLBACK_DECL(hoPredCtrl, m_indiP_timestamp)
pcf::IndiProperty m_indiP_reset_exploreRequest
int m_learning_iterations
pcf::IndiProperty m_indiP_explorationRms
DDSPC::PredictiveController * controller
pcf::IndiProperty m_indiP_intgain
eigenImage< realT > m_mapping_matrix
int processImage(void *curr_src, const dev::shmimT &dummy)
INDI_NEWCALLBACK_DECL(hoPredCtrl, m_indiP_loadRequest)
realT(* dark_pixget)(void *, size_t)
pcf::IndiProperty m_indiP_learningSteps
INDI_NEWCALLBACK_DECL(hoPredCtrl, m_indiP_zeroRequest)
int m_numFut
The number of future states to predict.
INDI_NEWCALLBACK_DECL(hoPredCtrl, m_indiP_clipval)
unsigned long long iterations
INDI_NEWCALLBACK_DECL(hoPredCtrl, m_indiP_controlToggle)
pcf::IndiProperty m_indiP_lambda
INDI_NEWCALLBACK_DECL(hoPredCtrl, m_indiP_intgain)
INDI_NEWCALLBACK_DECL(hoPredCtrl, m_indiP_updateControllerRequest)
realT m_inv_covariance
The starting point of the inverse covariance matrix.
int m_numHist
The number of past states to use for the prediction.
virtual int appLogic()
Implementation of the FSM for hoPredCtrl.
size_t m_pwfsHeight
The height of the image.
uint32_t m_dmWidth
The width of the image.
int map_command_vector_to_dmshmim()
virtual int appStartup()
Startup function.
std::string m_pupilMaskFilename
pcf::IndiProperty m_indiP_reset_cleanRequest
uint64_t loading_timestamp
pcf::IndiProperty m_indiP_clipval
uint32_t m_dmHeight
The height of the image.
INDI_NEWCALLBACK_DECL(hoPredCtrl, m_indiP_explorationSteps)
pcf::IndiProperty m_indiP_saveRequest
INDI_NEWCALLBACK_DECL(hoPredCtrl, m_indiP_gamma)
size_t m_measurement_size
realT m_gamma
The forgetting factore (0, 1)
dev::shmimMonitor< hoPredCtrl > shmimMonitorT
dev::shmimMonitor< hoPredCtrl, darkShmimT > darkMonitorT
eigenImage< realT > m_measurementVector
eigenImage< realT > m_shaped_command
INDI_NEWCALLBACK_DECL(hoPredCtrl, m_indiP_lambda)
std::string m_mapping_matrix_filename
INDI_NEWCALLBACK_DECL(hoPredCtrl, m_indiP_reset_bufferRequest)
bool m_use_predictive_control
eigenImage< realT > m_darkImage
Pointer to a function to extract the image data as our desired type realT.
int loadConfigImpl(mx::app::appConfigurator &_config)
Implementation of loadConfig logic, separated for testing.
realT m_lambda
The regularization parameter.
unsigned long long duration
virtual int appShutdown()
Shutdown the app.
eigenImage< realT > m_illuminated_actuators_mask
pcf::IndiProperty m_indiP_reset_modelRequest
bool m_darkSet
Pointer to a function to extract the image data as our desired type realT.
virtual void setupConfig()
INDI_NEWCALLBACK_DECL(hoPredCtrl, m_indiP_explorationRms)
pcf::IndiProperty m_indiP_learningIterations
uint8_t m_dmDataType
The ImageStreamIO type code.
INDI_NEWCALLBACK_DECL(hoPredCtrl, m_indiP_learningSteps)
pcf::IndiProperty m_indiP_controlToggle
size_t m_pwfsWidth
The width of the image.
size_t m_illuminatedPixels
int allocate(const dev::shmimT &dummy)
pcf::IndiProperty m_indiP_predictorToggle
pcf::IndiProperty m_indiP_timestamp
INDI_NEWCALLBACK_DECL(hoPredCtrl, m_indiP_reset_modelRequest)
realT average_pupil_intensity
pcf::IndiProperty m_indiP_loadRequest
float realT
Floating point type in which to do all calculations.
virtual void loadConfig()
INDI_NEWCALLBACK_DECL(hoPredCtrl, m_indiP_reset_cleanRequest)
eigenImage< realT > m_pupilMask
std::string m_refWavefront_filename
size_t m_quadWidth
The width of the image.
INDI_NEWCALLBACK_DECL(hoPredCtrl, m_indiP_learningIterations)
bool use_full_image_reconstructor
pcf::IndiProperty m_indiP_reset_bufferRequest
pcf::IndiProperty m_indiP_intleak
std::string m_interaction_matrix_filename
size_t m_quadHeight
The height of the image.
pcf::IndiProperty m_indiP_gamma
INDI_NEWCALLBACK_DECL(hoPredCtrl, m_indiP_intleak)
eigenImage< realT > m_refWavefront
size_t m_dmTypeSize
The size of the type, in bytes.
eigenImage< realT > m_interaction_matrix
~hoPredCtrl() noexcept
D'tor, declared and defined for noexcept.
pcf::IndiProperty m_indiP_updateControllerRequest
INDI_NEWCALLBACK_DECL(hoPredCtrl, m_indiP_saveRequest)
int set_pupil_mask(std::string pupil_mask_filename)
INDI_NEWCALLBACK_DECL(hoPredCtrl, m_indiP_predictorToggle)
#define INDI_NEWCALLBACK(prop)
Get the name of the static callback wrapper for a new property.
@ OPERATING
The device is operating, other than homing.
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.
const pcf::IndiProperty & ipRecv
updateIfChanged(m_indiP_angle, "target", m_angle)
INDI_NEWCALLBACK_DEFN(acesxeCtrl, m_indiP_windspeed)(const pcf
std::unique_lock< std::mutex > lock(m_indiMutex)
constexpr static logPrioT LOG_NOTICE
A normal but significant condition.
static std::string configSection()
static std::string indiPrefix()