7#ifndef t2wOffloader_hpp
8#define t2wOffloader_hpp
12#include <mx/improc/eigenCube.hpp>
13#include <mx/improc/eigenImage.hpp>
14#include <mx/improc/milkImage.hpp>
15#include <mx/sigproc/gramSchmidt.hpp>
16#include <mx/math/templateBLAS.hpp>
18#include "../../libMagAOX/libMagAOX.hpp"
19#include "../../magaox_git_version.h"
147 mx::app::appConfigurator &
_config );
246 config.add(
"integrator.fpsSource",
248 "integrator.fpsSource",
254 "Device name for getting fps of the loop. This device should have *.fps.current. Default is camwfs" );
256 config.add(
"integrator.navgSource",
258 "integrator.navgSource",
264 "Device name for getting navg of tweeter-ave. This device should have *.fps.current. Default is "
267 config.add(
"offload.respMPath",
275 "The path to the response matrix." );
277 config.add(
"offload.channel",
285 "The DM channel to offload to." );
287 config.add(
"offload.gain",
295 "The starting offload gain. Default is 0.1." );
297 config.add(
"offload.leak",
305 "The starting offload leak. Default is 0.0." );
307 config.add(
"offload.startupOffloading",
309 "offload.startupOffloading",
315 "Flag controlling whether offloading is on at startup. Default is false." );
317 config.add(
"offload.actLim",
325 "The woofer actuator command limit. Default is 7.0." );
327 config.add(
"offload.tweeterModes",
329 "offload.tweeterModes",
335 "File containing the tweeter modes to use for offloading" );
337 config.add(
"offload.tweeterMask",
339 "offload.tweeterMask",
345 "File containing the tweeter mask." );
347 config.add(
"offload.wooferMask",
349 "offload.wooferMask",
355 "File containing the woofer mask." );
357 config.add(
"offload.maxModes",
365 "Maximum number of modes for modal offloading." );
367 config.add(
"offload.numModes",
375 "Number of modes to offload. 0 means use actuator offloading." );
377 config.add(
"offload.loopNumber",
379 "offload.loopNUmber",
385 "The aol loop number to use. Default is 0." );
411 if(
_config.isSet(
"offload.startupOffloading" ) )
563 static_cast<void>(
dummy );
621 static_cast<void>(
dummy );
639 mx::sys::microSleep( 1 );
718 mx::sys::microSleep( 1 );
773 mx::sys::microSleep( 1 );
804 mx::improc::eigenCube<float>
tmodes;
806 mx::fits::fitsFile<float>
ff;
818 for(
int p = 0; p <
tmodes.planes(); ++p )
821 float norm = (
tmodes.image( p ) ).square().sum();
835 mx::improc::eigenImage<realT>
win,
wout;
838 wout.resize( 11, 11 );
845 Eigen::Map<Eigen::Matrix<
float, -1, -1>>(
wout.data(),
wout.rows() *
wout.cols(), 1 ) =
893 if( indiTargetUpdate( m_indiP_gain, target,
ipRecv,
true ) < 0 )
895 log<software_error>( {
"" } );
899 recordLoopGain(
true );
919 if( indiTargetUpdate( m_indiP_leak, target,
ipRecv,
true ) < 0 )
921 log<software_error>( {
"" } );
925 recordLoopGain(
true );
943 if( indiTargetUpdate( m_indiP_actLim, target,
ipRecv,
true ) < 0 )
945 log<software_error>( {
"" } );
949 recordLoopGain(
true );
958 log<text_log>(
"set actuator limit to " + std::to_string( m_actLim ),
logPrio::LOG_NOTICE );
967 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On )
980 if( indiTargetUpdate( m_indiP_numModes, target,
ipRecv,
true ) < 0 )
982 log<software_error>( {
"" } );
986 recordOffloading(
true );
990 if( m_numModes > m_maxModes )
992 log<text_log>( std::format(
"maximum number of offloadings modes is {}", m_maxModes ),
logPrio::LOG_WARNING );
993 m_numModes = m_maxModes;
999 log<text_log>(
"set number of modes to " + std::to_string( m_numModes ),
logPrio::LOG_NOTICE );
1009 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::On )
1016 recordLoopGain(
true );
1017 m_offloading =
true;
1021 updateSwitchIfChanged( m_indiP_offloadToggle,
"toggle", pcf::IndiElement::On,
INDI_OK );
1027 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::Off )
1031 recordLoopGain(
true );
1032 m_offloading =
false;
1036 updateSwitchIfChanged( m_indiP_offloadToggle,
"toggle", pcf::IndiElement::Off,
INDI_IDLE );
1048 if(
ipRecv.find(
"current" ) !=
true )
1053 std::lock_guard<std::mutex> guard( m_indiMutex );
1055 realT fps =
ipRecv[
"current"].get<
float>();
1070 if(
ipRecv.find(
"current" ) !=
true )
1075 std::lock_guard<std::mutex> guard( m_indiMutex );
1077 realT navg =
ipRecv[
"current"].get<
float>();
1079 if( navg != m_navg )
1101 static float gain{ -1000 };
1102 static float leak{ 0 };
1103 static float limit{ 0 };
The base-class for XWCTk 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.
static int log(const typename logT::messageT &msg, logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry.
int createROIndiNumber(pcf::IndiProperty &prop, const std::string &propName, const std::string &propLabel="", const std::string &propGroup="")
Create a ReadOnly INDI Number property.
int registerIndiPropertyReadOnly(pcf::IndiProperty &prop)
Register an INDI property which is read only.
std::mutex m_indiMutex
Mutex for locking INDI communications.
uint32_t m_width
The width of the images in the stream.
uint32_t m_height
The height of the images in the stream.
uint8_t m_dataType
The ImageStreamIO type code.
size_t m_typeSize
The size of the type, in bytes. Result of sizeof.
int allocate(const dev::shmimT &dummy)
t2wOffloader()
Default c'tor.
int recordLoopGain(bool force=false)
mx::improc::eigenImage< realT > m_twRespM
mx::improc::eigenImage< realT > m_tweeterMask
INDI_NEWCALLBACK_DECL(t2wOffloader, m_indiP_actLim)
mx::improc::eigenImage< realT > m_tweeter
pcf::IndiProperty m_indiP_leak
int processImage(void *curr_src, const dev::shmimT &dummy)
uint32_t m_dmHeight
The height of the image.
friend class t2wOffloader_test
uint32_t m_navg
Current navg from the averager.
~t2wOffloader() noexcept
D'tor, declared and defined for noexcept.
pcf::IndiProperty m_indiP_fps
pcf::IndiProperty m_indiP_fpsSource
pcf::IndiProperty m_indiP_numModes
virtual int appLogic()
Implementation of the FSM for t2wOffloader.
std::mutex m_shmimMutex
Mutex for locking shared memory access.
mx::improc::eigenCube< float > m_tModesOrtho
INDI_SETCALLBACK_DECL(t2wOffloader, m_indiP_navgSource)
dev::telemeter< t2wOffloader > telemeterT
int updateFPS()
Update the effective FPS after an navg or fps change.
std::string m_tweeterModeFile
File containing the tweeter modes to use for offloading.
virtual int appStartup()
Startup function.
float realT
Floating point type in which to do all calculations.
pcf::IndiProperty m_indiP_offloadToggle
pcf::IndiProperty m_indiP_navgSource
INDI_NEWCALLBACK_DECL(t2wOffloader, m_indiP_gain)
virtual void setupConfig()
int loadConfigImpl(mx::app::appConfigurator &_config)
Implementation of loadConfig logic, separated for testing.
float m_actLim
the upper limit on woofer actuator commands. default is 7.0.
int recordOffloading(bool force=false)
INDI_NEWCALLBACK_DECL(t2wOffloader, m_indiP_leak)
INDI_NEWCALLBACK_DECL(t2wOffloader, m_indiP_offloadToggle)
mx::improc::eigenImage< realT > m_woofer
mx::improc::milkImage< realT > m_modevalDMf
uint32_t m_dmWidth
The width of the image.
int recordTelem(const telem_loopgain *)
mx::improc::eigenImage< realT > m_wooferDelta
INDI_NEWCALLBACK_DECL(t2wOffloader, m_indiP_zero)
INDI_SETCALLBACK_DECL(t2wOffloader, m_indiP_fpsSource)
std::string m_tweeterMaskFile
float m_fps
Current FPS from the FPS source.
std::string m_wooferMaskFile
mx::improc::milkImage< float > m_wooferMask
virtual void loadConfig()
mx::improc::eigenImage< realT > m_modeDeltaAmps
dev::shmimMonitor< t2wOffloader > shmimMonitorT
virtual int appShutdown()
Shutdown the app.
mx::improc::milkImage< realT > m_modevalDM
INDI_NEWCALLBACK_DECL(t2wOffloader, m_indiP_numModes)
pcf::IndiProperty m_indiP_gain
uint8_t m_dmDataType
The ImageStreamIO type code.
pcf::IndiProperty m_indiP_actLim
mx::improc::eigenCube< float > m_wModes
std::string m_twRespMPath
size_t m_dmTypeSize
The size of the type, in bytes.
pcf::IndiProperty m_indiP_zero
#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 INDI_SETCALLBACK_DEFN(class, prop)
Define the callback for a set property request.
#define REG_INDI_SETPROP(prop, devName, propName)
Register a SET INDI property with the class, 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.
const pcf::IndiProperty & ipRecv
updateIfChanged(m_indiP_angle, "target", m_angle)
std::unique_lock< std::mutex > lock(m_indiMutex)
static constexpr logPrioT LOG_NOTICE
A normal but significant condition.
static constexpr logPrioT LOG_WARNING
A condition has occurred which may become an error, but the process continues.
#define SHMIMMONITOR_APP_SHUTDOWN
Call shmimMonitorT::appShutdown with error checking for shmimMonitor.
#define SHMIMMONITOR_APP_LOGIC
Call shmimMonitorT::appLogic with error checking for shmimMonitor.
#define SHMIMMONITOR_APP_STARTUP
Call shmimMonitorT::appStartup with error checking for shmimMonitor.
#define SHMIMMONITOR_LOAD_CONFIG(cfig)
Call shmimMonitorT::loadConfig with error checking for shmimMonitor.
#define SHMIMMONITOR_UPDATE_INDI
Call shmimMonitorT::updateINDI with error checking for shmimMonitor.
#define SHMIMMONITOR_SETUP_CONFIG(cfig)
Call shmimMonitorT::setupConfig with error checking for shmimMonitor.
A device base class which saves telemetry.
int checkRecordTimes(const telT &tel, telTs... tels)
Check the time of the last record for each telemetry type and make an entry if needed.
Log entry recording the build-time git state.
Log entry recording the build-time git state.
#define TELEMETER_APP_LOGIC
Call telemeter::appLogic with error checking.
#define TELEMETER_LOAD_CONFIG(cfig)
Call telemeter::loadConfig with error checking.
#define TELEMETER_APP_STARTUP
Call telemeter::appStartup with error checking.
#define TELEMETER_SETUP_CONFIG(cfig)
Call telemeter::setupConfig with error checking.
#define TELEMETER_APP_SHUTDOWN
Call telemeter::appShutdown with error checking.