11 #include "../../libMagAOX/libMagAOX.hpp"
12 #include "../../magaox_git_version.h"
16 #include <asdkWrapper.h>
206 config.add(
"dm.serialNumber",
"",
"dm.serialNumber", argType::Required,
"dm",
"serialNumber",
false,
"string",
"The ALPAO serial number used to find the default config directory.");
207 config.add(
"dm.satThresh",
"",
"dm.satThresh", argType::Required,
"dm",
"satThresh",
false,
"string",
"Threshold above which to log saturation.");
239 log<software_critical>({__FILE__,__LINE__});
245 log<software_critical>({__FILE__,__LINE__,
"calibration not loaded properly"});
312 m_dm = asdkInit(ser.c_str());
315 asdkGetLastError(&aerr,
nullptr, 0);
319 asdkGetLastError(&aerr, err,
sizeof(err));
320 log<software_error>({__FILE__, __LINE__, std::string(
"DM initialization failed: ") + err});
329 asdkGetLastError(&aerr, err,
sizeof(err));
330 return log<
software_error, -1>({__FILE__, __LINE__, std::string(
"DM initialization failed. NULL pointer: ") + err});
337 if(asdkGet(
m_dm,
"NbOfActuator", &tmp ) < 0)
340 asdkGetLastError(&aerr, err,
sizeof(err));
341 return log<
software_error, -1>({__FILE__, __LINE__, std::string(
"Getting number of actuators failed: ") + err});
350 return log<
software_error, -1>({__FILE__, __LINE__,
"DM initialization failed. Error zeroing DM."});
359 return log<
software_error, -1>({__FILE__, __LINE__,
"DM initialization failed. Failed to get actuator mapping."});
364 return log<
software_error, -1>({__FILE__, __LINE__,
"DM initialization failed. null pointer."});
376 return log<
software_error, -1>({__FILE__, __LINE__,
"DM not initialized (NULL pointer)"});
381 return log<
software_error, -1>({__FILE__, __LINE__,
"DM not initialized (number of actuators)"});
384 Scalar * dminputs = (Scalar*) calloc(
m_nbAct,
sizeof( Scalar ) );
387 int ret = asdkSend(
m_dm, dminputs);
396 asdkGetLastError(&aerr, err,
sizeof(err));
398 return log<
software_error,-1>({__FILE__, __LINE__, std::string(
"Error zeroing DM: ") + err});
401 log<text_log>(
"DM zeroed");
418 for (UInt idx = 0; idx <
m_nbAct; ++idx)
431 for (UInt idx = 0 ; idx <
m_nbAct ; ++idx)
449 for (UInt idx = 0; idx <
m_nbAct; ++idx)
478 pthread_kill(
m_smThread.native_handle(), SIGUSR1);
485 return log<
software_error,-1>({__FILE__, __LINE__,
"DM release failed. Error zeroing DM."});
492 asdkGetLastError(&aerr,
nullptr, 0);
496 asdkGetLastError(&aerr, err,
sizeof(err));
497 return log<
software_error,-1>({__FILE__, __LINE__, std::string(
"DM reset failed: ") + err});
503 asdkGetLastError(&aerr,
nullptr, 0);
507 asdkGetLastError(&aerr, err,
sizeof(err));
508 return log<
software_error, -1>({__FILE__, __LINE__, std::string(
"DM release failed: ") + err});
532 std::string calibpath =
m_calibPath +
"/" + ser +
"_userconfig.txt";
535 fp = fopen(calibpath.c_str(),
"r");
538 return log<
software_error,-1>({__FILE__, __LINE__,
"Could not read configuration file at " + calibpath});
541 calibvals = (Scalar*) malloc(2*
sizeof(Scalar));
543 while ((read = getline(&line, &len, fp)) != -1)
546 calibvals[idx] = strtod(line, NULL);
558 log<text_log>(
"ALPAO " +
m_serialNumber +
": Using stroke and volume calibration from " + calibpath);
576 std::string calibpath =
m_calibPath +
"/" + ser +
"_actuator_mapping.fits";
578 if ( !fits_open_image(&fptr, calibpath.c_str(), READONLY, &status) )
583 if (fits_get_hdu_type(fptr, &hdutype, &status) || hdutype != IMAGE_HDU) {
584 printf(
"Error: this program only works on images, not tables\n");
588 fits_get_img_dim(fptr, &naxis, &status);
589 fits_get_img_size(fptr, 2, naxes, &status);
591 if (status || naxis != 2) {
592 printf(
"Error: NAXIS = %d. Only 2-D images are supported.\n", naxis);
596 int * pix = (
int *) malloc(naxes[0] *
sizeof(
int));
599 printf(
"Memory allocation error\n");
609 for (fpixel[1] = naxes[1]; fpixel[1] >= 1; fpixel[1]--)
612 if (fits_read_pix(fptr, TINT, fpixel, naxes[0],0, pix,0, &status))
616 for (
int ii = 0; ii < naxes[0]; ii++) {
623 fits_close_file(fptr, &status);
629 fits_report_error(stderr, status);
634 log<text_log>(
"ALPAO " +
m_serialNumber +
": Using actuator mapping from " + calibpath);
The base-class for MagAO-X applications.
stateCodes::stateCodeT state()
Get the current state code.
int shutdown()
Get the value of the shutdown flag.
static int log(const typename logT::messageT &msg, logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry.
bool powerOnWaitElapsed()
This method tests whether the power on wait time has elapsed.
The MagAO-X ALPAO DM Controller.
Scalar m_max_stroke
The maximum allowable stroke.
~alpaoCtrl() noexcept
D'tor.
virtual void setupConfig()
Setup the configuration system.
std::string m_serialNumber
The ALPAO serial number used to find the default config directory.
Scalar * m_dminputs
Pre-allocated command vector, used only in commandDM.
asdkDM * m_dm
ALPAO SDK handle for the DM.
Scalar m_volume_factor
the volume factor to convert from displacement to commands
int loadConfigImpl(mx::app::appConfigurator &_config)
Implementation of loadConfig logic, separated for testing.
virtual int appShutdown()
Shutdown the app.
int get_actuator_mapping()
Read the actuator mapping from a FITS file.
int parse_calibration_file()
Parse the ALPAO calibration file.
int initDM()
Initialize the DM and prepare for operation.
virtual int appLogic()
Implementation of the FSM for alpaoCtrl.
float realT
This defines the datatype used to signal the DM using the ImageStreamIO library.
int * m_actuator_mapping
Array containing the mapping from 2D grid position to linear index in the command vector.
virtual int appStartup()
Startup function.
int releaseDM()
Release the DM, making it safe to turn off power.
int commandDM(void *curr_src)
Send a command to the DM.
virtual int onPowerOff()
Cleanup after a power off.
alpaoCtrl()
Default c'tor.
int zeroDM()
Zero all commands on the DM.
UInt m_nbAct
The number of actuators.
friend class alpaoCtrl_test
virtual int whilePowerOff()
Maintenace while powered off.
long m_satThresh
Threshold above which to log saturation.
virtual void loadConfig()
Load the configuration.
std::string m_calibPath
The path to this DM's calibration files.
std::string m_calibRelDir
The directory relative to the calibPath. Set this before calling dm<derivedT,realT>::loadConfig().
int appShutdown()
DM shutdown.
mx::improc::eigenImage< uint8_t > m_instSatMap
The instantaneous saturation map, 0/1, set by the commandDM() function of the derived class.
int loadConfig(mx::app::appConfigurator &config)
load the configuration system results
int whilePowerOff()
DM Poweroff Updates.
int appStartup()
Startup function.
int setupConfig(mx::app::appConfigurator &config)
Setup the configuration system.
int onPowerOff()
DM Poweroff.
int appLogic()
DM application logic.
int appStartup()
Startup function.
int appLogic()
Checks the shmimMonitor thread.
std::thread m_smThread
A separate thread for the actual monitoring.
int appShutdown()
Shuts down the shmimMonitor thread.
@ OPERATING
The device is operating, other than homing.
@ POWEROFF
The device power is off.
@ READY
The device is ready for operation, but is not operating.
@ POWERON
The device power is on.
std::string toLower(std::string const &s)
constexpr static logPrioT LOG_ERROR
An error has occured which the software will attempt to correct.
constexpr static logPrioT LOG_WARNING
A condition has occurred which may become an error, but the process continues.
constexpr static logPrioT LOG_NOTICE
A normal but significant condition.