26 #include "../../libMagAOX/libMagAOX.hpp"
27 #include "../../magaox_git_version.h"
225 config.add(
"dm.serialNumber",
"",
"dm.serialNumber", argType::Required,
"dm",
"serialNumber",
false,
"string",
"The BMC serial number used to find correct DM Profile.");
226 config.add(
"dm.calibRelDir",
"",
"dm.calibRelDir", argType::Required,
"dm",
"calibRelDir",
false,
"string",
"Used to find the default config directory.");
227 config.add(
"dm.satThresh",
"",
"dm.satThresh", argType::Required,
"dm",
"satThresh",
false,
"string",
"Threshold above which to log saturation.");
256 log<software_critical>({__FILE__,__LINE__});
262 log<software_critical>({__FILE__,__LINE__,
"calibration not loaded properly"});
329 ret = BMCOpen(&
m_dm, ser.c_str());
336 err = BMCErrorString(ret);
345 log<text_log>(
"DM initialization failed. Couldn't open DM handle.",
logPrio::LOG_ERROR);
357 map_lut = (uint32_t *)malloc(
sizeof(uint32_t)*MAX_DM_SIZE);
358 ret = BMCLoadMap(&
m_dm, NULL, map_lut);
363 err = BMCErrorString(ret);
364 log<text_log>(std::string(
"DM initialization failed. Couldn't load map.") + err,
logPrio::LOG_ERROR);
385 for (uint32_t idx = 0; idx <
m_nbAct; ++idx)
392 log<text_log>(
"DM initialization failed. Failed to get actuator mapping.",
logPrio::LOG_ERROR);
421 double * dminputs = (
double*) calloc(
m_nbAct,
sizeof(
double ) );
424 BMCRC ret = BMCSetArray(&
m_dm, dminputs, NULL);
432 err = BMCErrorString(ret);
437 log<text_log>(
"DM zeroed");
452 dmT::m_tact0 = mx::sys::get_curr_time();
455 for (uint32_t idx = 0; idx <
m_nbAct; ++idx)
482 dmT::m_tact1 = mx::sys::get_curr_time();
489 dmT::m_tact2 = mx::sys::get_curr_time();
497 err = BMCErrorString(ret);
503 dmT::m_tact3 = mx::sys::get_curr_time();
507 for (uint32_t idx = 0; idx <
m_nbAct; ++idx)
527 dmT::m_tact4 = mx::sys::get_curr_time();
546 pthread_kill(
m_smThread.native_handle(), SIGUSR1);
559 ret = BMCClearArray(&
m_dm);
564 err = BMCErrorString(ret);
570 ret = BMCClose(&
m_dm);
577 err = BMCErrorString(ret);
601 std::string calibpath =
m_calibPath +
"/" +
"bmc_2k_userconfig.txt";
604 fp = fopen(calibpath.c_str(),
"r");
607 log<text_log>(
"Could not read configuration file at " + calibpath,
logPrio::LOG_ERROR);
611 calibvals = (
double*) malloc(2*
sizeof(
double));
613 while ((read = getline(&line, &len, fp)) != -1)
616 calibvals[idx] = strtod(line, NULL);
628 log<text_log>(
"BMC " +
m_serialNumber +
": Using stroke and volume calibration from " + calibpath);
643 std::string calibpath =
m_calibPath +
"/" +
"bmc_2k_actuator_mapping.fits";
645 if ( !fits_open_image(&fptr, calibpath.c_str(), READONLY, &status) )
650 if (fits_get_hdu_type(fptr, &hdutype, &status) || hdutype != IMAGE_HDU) {
651 printf(
"Error: this program only works on images, not tables\n");
655 fits_get_img_dim(fptr, &naxis, &status);
656 fits_get_img_size(fptr, 2, naxes, &status);
658 if (status || naxis != 2) {
659 printf(
"Error: NAXIS = %d. Only 2-D images are supported.\n", naxis);
663 int * pix = (
int *) malloc(naxes[0] *
sizeof(
int));
666 printf(
"Memory allocation error\n");
676 for (fpixel[1] = 1; fpixel[1] <= naxes[1]; fpixel[1]++)
679 if (fits_read_pix(fptr, TINT, fpixel, naxes[0],0, pix,0, &status))
683 for (
int ii = 0; ii < naxes[0]; ii++) {
690 fits_close_file(fptr, &status);
696 fits_report_error(stderr, status);
700 log<text_log>(
"BMC " +
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.
The MagAO-X BMC DM Controller.
uint32_t m_nbAct
The number of actuators.
double m_act_gain
Actuator gain (microns/volt)
bool m_dmopen
Track whether the DM connection has been opened.
virtual int whilePowerOff()
Maintenace while powered off.
DM m_dm
BMC SDK handle for the DM.
int commandDM(void *curr_src)
Send a command to the DM.
dev::shmimMonitor< bmcCtrl > shmimMonitorT
int initDM()
Initialize the DM and prepare for operation.
virtual void setupConfig()
Setup the configuration system.
double * m_dminputs
Pre-allocated command vector, used only in commandDM.
std::string m_serialNumber
The BMC serial number used to open the correct DM profile.
double m_volume_factor
the volume factor to convert from displacement to commands
virtual int appLogic()
Implementation of the FSM for bmcCtrl.
long m_satThresh
Threshold above which to log saturation.
virtual int appShutdown()
Shutdown the app.
virtual void loadConfig()
Load the configuration.
friend class bmcCtrl_test
int releaseDM()
Release the DM, making it safe to turn off power.
int zeroDM()
Zero all commands on the DM.
int loadConfigImpl(mx::app::appConfigurator &_config)
Implementation of loadConfig logic, separated for testing.
virtual int onPowerOff()
Cleanup after a power off.
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.
int get_actuator_mapping()
Read the actuator mapping from a FITS file.
virtual int appStartup()
Startup function.
dev::dm< bmcCtrl, float > dmT
int parse_calibration_file()
Parse the BMC calibration file.
~bmcCtrl() noexcept
D'tor.
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.
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.