20#include "../../libMagAOX/libMagAOX.hpp"
21#include "../../magaox_git_version.h"
275 std::transform(
clean.begin(),
278 [](
unsigned char c ) { return static_cast<char>( std::tolower( c ) ); } );
349 const std::string &response
354 if(
clean.find(
"medium" ) != std::string::npos ||
clean ==
"med" )
360 if(
clean.find(
"high" ) != std::string::npos )
366 if(
clean.find(
"low" ) != std::string::npos )
486 config.add(
"camera.serialBaud",
494 "The Camera Link serial baud rate for C-RED 2 CLI commands. Default is 115200." );
511 static_cast<unsigned>(
m_nextROI.bin_x ),
512 static_cast<unsigned>(
m_nextROI.bin_y ),
614 std::string response;
711 if( !
lock.owns_lock() )
919 std::string response;
932 return log<
text_log, -1>(
"C-RED 2 rejected command '" +
command +
"' with response: " + response,
941 std::string response;
948 if(
sendCommand( response,
"cropping raw",
false ) < 0 ||
968 if( startColumn == 0 && endColumn == 0 && startRow == 0 && endRow == 0 )
970 if(
sendCommand( response,
"cropping columns raw",
false ) < 0 ||
974 {
__FILE__,
__LINE__,
"failed to query current cropping columns: " + response } );
977 if(
sendCommand( response,
"cropping rows raw",
false ) < 0 ||
981 {
__FILE__,
__LINE__,
"failed to query current cropping rows: " + response } );
1052 if(
m_pdv ==
nullptr )
1076 "EDT serial baud verification failed: expected " +
1087 std::string response;
1091 const std::string
setpointCommand(
"temperatures snake setpoint raw" );
1094 return log<text_log, 0>(
"transient C-RED 2 temperature refresh failure; keeping previous cached values: " +
1174 std::string response;
1195 std::string response;
1205 if(
fanMode.find(
"auto" ) == std::string::npos &&
fanMode.find(
"manual" ) == std::string::npos )
1215 if(
fanMode.find(
"auto" ) != std::string::npos )
1223 if(
fanMode.find(
"manual" ) == std::string::npos )
1228 if(
sendCommand( response,
"fan speed raw" ) < 0 )
1251 std::string response;
1274 std::string response;
1289 if(
clean.find(
"off" ) != std::string::npos )
1293 else if(
clean.find(
"on" ) != std::string::npos )
1305 if(
clean.find(
"off" ) != std::string::npos )
1309 else if(
clean.find(
"on" ) != std::string::npos )
1330 std::string response;
1389 "temperature control is setpoint-driven for C-RED 2; choose a target below 20 C to cool",
1430 return log<
text_log, -1>(
"attempt to set fps outside valid range: " + std::to_string(
m_fpsSet ),
1523 {
return static_cast<int>( std::lround(
static_cast<double>( value ) /
static_cast<double>(
step ) ) ) *
step; };
1529 width = std::clamp( width, 32,
m_full_w );
1532 height = std::clamp( height, 4,
m_full_h );
1534 int startColumn =
static_cast<int>( std::lround(
m_nextROI.x - 0.5f * (
static_cast<float>( width ) - 1.0f ) ) );
1535 int startRow =
static_cast<int>( std::lround(
m_nextROI.y - 0.5f * (
static_cast<float>( height ) - 1.0f ) ) );
1540 startColumn = std::clamp( startColumn, 0,
m_full_w - width );
1541 startRow = std::clamp( startRow, 0,
m_full_h - height );
1545 m_nextROI.x = startColumn + 0.5f * (
static_cast<float>( width ) - 1.0f );
1546 m_nextROI.y = startRow + 0.5f * (
static_cast<float>( height ) - 1.0f );
1590 fout <<
"camera_class: \"FirstLightImaging\"\n";
1591 fout <<
"camera_model: \"C-RED 2\"\n";
1592 fout <<
"camera_info: \"" << width <<
"x" << height <<
" (4-tap, freerun)\"\n";
1593 fout <<
"width: " << width <<
"\n";
1594 fout <<
"height: " << height <<
"\n";
1595 fout <<
"depth: 16\n";
1596 fout <<
"extdepth: 16\n";
1597 fout <<
"rbtfile: aiagcl.bit\n";
1598 fout <<
"CL_DATA_PATH_NORM: 3f # four tap\n";
1599 fout <<
"CL_CFG_NORM: 02\n";
1600 fout <<
"CL_CFG2_NORM: 40\n";
1601 fout <<
"method_framesync: EMULATE_TIMEOUT\n";
1602 fout <<
"htaps: 4\n";
1604 fout <<
"serial_term: <0A>\n";
1605 fout <<
"serial_waitc: 0D\n";
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.
stateCodes::stateCodeT state()
Get the current state code.
int powerState()
Returns the current power state.
int m_shutdown
Flag to signal it's time to shutdown. When not 0, the main loop exits.
int powerStateTarget()
Returns the target power state.
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.
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.
std::string configName()
Get the config name.
MagAO-X application to control the C-RED 2 camera.
int checkNextROI()
Validate and normalize the requested ROI.
std::recursive_mutex m_cameraMutex
Protects serial command traffic and EDT reconfiguration.
int getFanSpeed()
Query and update the current fan-control state.
float fps()
Return the currently measured frame rate.
virtual int appStartup()
Startup function.
int setTempControl()
Implement the C-RED 2 temperature-controller toggle semantics.
std::string m_configFile
Absolute path to the temporary EDT configuration file.
int setTempSetPt()
Send the current target detector temperature setpoint to the camera.
int checkRecordTimes()
Check the telemetry record timers.
virtual int onPowerOff()
Actions required when the camera power turns off.
dev::stdCamera< cred2Ctrl > stdCameraT
int loadImageIntoStream(void *dest)
Copy the current EDT image into the output stream.
dev::frameGrabber< cred2Ctrl > frameGrabberT
int reconfig()
Reconfigure the EDT board for the pending ROI.
int syncROIFromCamera()
Query the camera for its current ROI and synchronize local state.
int configureAcquisition()
Configure camera-side ROI settings before acquisition starts.
static constexpr bool c_frameGrabber_flippable
Expose image flip controls through the framegrabber.
int getAnalogGain()
Query and update the current analog-gain state.
static constexpr bool c_stdCamera_fps
Expose FPS status.
virtual void loadConfig()
Load the configuration system results.
int recordTemps(bool force=false)
Record the detailed C-RED 2 temperature telemetry when values change.
static constexpr bool c_edtCamera_relativeConfigPath
Use an absolute temporary EDT config path.
static constexpr bool c_stdCamera_tempControl
Expose temperature setpoint control.
int setLED()
Send the requested LED state to the camera.
bool m_cameraCropEnabled
Tracks whether this controller has enabled camera-side cropping.
pcf::IndiProperty m_indiP_temps
Property reporting the detailed C-RED 2 temperature channels.
static constexpr bool c_stdCamera_cropMode
Do not expose crop-mode controls separately.
int powerOnDefaults()
Set defaults for a power-on state.
virtual void setupConfig()
Setup the configuration system.
static constexpr bool c_stdCamera_analogGain
Expose discrete analog-gain controls.
int updateFPSLimits()
Query and update the current camera FPS limits.
int getLEDState()
Query and update the current LED state.
int loadConfigImpl(mx::app::appConfigurator &config)
Implementation of loadConfig logic with standard helper-macro error handling.
static constexpr bool c_stdCamera_usesROI
Expose ROI controls.
static constexpr bool c_stdCamera_readoutSpeed
Do not expose readout-speed controls.
int setAnalogGain()
Send the requested analog-gain mode to the camera.
virtual int appShutdown()
Shutdown function.
static constexpr bool c_stdCamera_usesStateString
Do not expose a dark-management state string.
pcf::IndiProperty m_indiP_fpsLimits
Property reporting the current C-RED 2 minimum and maximum FPS.
static constexpr bool c_stdCamera_emGain
Do not expose EM-gain controls.
int setFPS()
Send the requested frame rate to the camera.
int setExpTime()
Required by stdCamera, but unused for C-RED 2.
int acquireAndCheckValid()
Wait for and validate the next acquired image.
static constexpr bool c_stdCamera_synchro
Do not expose synchro controls in the first pass.
static constexpr bool c_stdCamera_temp
Expose detector temperature status.
int setNextROI()
Request that the next valid ROI be applied through reconfiguration.
virtual int appLogic()
Main FSM logic.
int startAcquisition()
Start frame acquisition on the EDT board.
static constexpr bool c_stdCamera_fpsCtrl
Expose FPS controls.
int getTemps()
Query and update the camera temperature channels.
static constexpr bool c_stdCamera_fanSpeed
Expose fan-speed controls.
int m_roiSettleCounter
Number of main-loop cycles to skip serial status polling after ROI changes.
int writeConfig()
Write the temporary EDT configuration file for the pending ROI.
int getFPS()
Query and update the current camera frame rate.
cred2Ctrl()
Default c'tor.
int setSerialBaud()
Apply and verify the configured Camera Link serial baud rate.
int recordTelem(const cred2_temps *)
Record the detailed C-RED 2 temperature telemetry.
dev::telemeter< cred2Ctrl > telemeterT
~cred2Ctrl() noexcept
D'tor, declared and defined for noexcept.
int issueCommand(const std::string &command, bool allowNoResponse=false)
Send a command that should return a success acknowledgement.
int sendCommand(std::string &response, const std::string &command, bool logFailure=true)
Send a command over Camera Link serial and clean the response.
static constexpr bool c_stdCamera_vShiftSpeed
Do not expose vertical-shift controls.
int setFanSpeed()
Send the requested fan-control mode to the camera.
static constexpr bool c_stdCamera_led
Expose status LED controls.
cred2Temps m_temps
Cached camera temperature values used for INDI and telemetry updates.
virtual int whilePowerOff()
Actions required while the camera remains powered off.
static constexpr bool c_stdCamera_exptimeCtrl
Do not expose exposure-time controls.
static constexpr bool c_stdCamera_usesModes
Use one synthetic runtime mode rather than INDI modes.
int m_serialBaud
Camera Link serial baud rate used for C-RED 2 CLI access.
static constexpr bool c_stdCamera_hasShutter
Do not expose shutter controls.
MagAO-X EDT framegrabber interface.
u_char * m_image_p
The image data grabbed.
int m_raw_height
The height of the frame, according to the framegrabber.
PdvDev * m_pdv
The EDT PDV device handle.
int pdvSerialWriteRead(std::string &response, const std::string &command, bool logErrors=true)
Send a serial command over cameralink and retrieve the response.
void setupConfig(mx::app::appConfigurator &config)
Setup the configuration system.
void loadConfig(mx::app::appConfigurator &config)
load the configuration system results
int m_raw_width
The width of the frame, according to the framegrabber.
int appShutdown()
Application the shutdown.
timespec m_currImageTimestamp
The timestamp of the current image.
uint32_t m_width
The width of the image, once deinterlaced etc.
int recordFGTimings(bool force=false)
size_t m_typeSize
The size of the type, in bytes. Result of sizeof.
uint8_t m_dataType
The ImageStreamIO type code.
bool m_reconfig
Flag to set if a camera reconfiguration requires a framegrabber reset.
uint32_t m_height
The height of the image, once deinterlaced etc.
MagAO-X standard camera interface.
float m_fpsSet
The commanded fps, as set by user.
pcf::IndiProperty m_indiP_roi_y
Property used to set the ROI x center coordinate.
int m_full_currbin_w
The current-binning full ROI width.
std::vector< std::string > m_analogGainNames
Valid analog-gain option names for the INDI selection switch.
float m_default_x
Power-on ROI center x coordinate.
std::string m_tempControlStatusStr
Camera specific description of temperature control status.
int m_full_bin_x
The x-binning in the full ROI.
std::vector< std::string > m_fanSpeedNames
Valid fan-control option names for the INDI selection switch.
std::string m_analogGainNameSet
Requested analog-gain option name.
float m_full_currbin_x
The current-binning full ROI center x coordinate.
int m_full_w
The full ROI width.
std::string m_nextMode
The mode to be set by the next reconfiguration.
int m_default_bin_x
Power-on ROI x binning.
int m_default_w
Power-on ROI width.
bool m_ledStateSet
Requested status LED state.
int recordCamera(bool force=false)
float m_stepFPS
The FPS step size, used for INDI attributes.
int m_default_h
Power-on ROI height.
pcf::IndiProperty m_indiP_roi_last
Property used to trigger setting the last ROI.
pcf::IndiProperty m_indiP_roi_h
Property used to set the ROI height.
std::string m_fanSpeedNameSet
Requested fan-control option name.
int m_full_h
The full ROI height.
bool m_ledStateValid
True once the current LED state is known.
std::string m_analogGainName
Current analog-gain option name.
int m_full_bin_y
The y-binning in the full ROI.
float m_full_y
The full ROI center y coordinate.
float m_maxFPS
The maximum FPS, used for INDI attributes.
float m_ccdTempSetpt
The desired temperature, in C.
bool m_tempControlStatus
Whether or not temperature control is active.
bool m_defaultLEDState
The default LED state to apply after power on.
pcf::IndiProperty m_indiP_roi_w
Property used to set the ROI width.
pcf::IndiProperty m_indiP_roi_default
Property used to trigger setting the default and startup ROI.
std::string m_modeName
The current mode name.
pcf::IndiProperty m_indiP_roi_bin_x
Property used to set the ROI x binning.
std::string m_startupMode
The camera mode to load during first init after a power-on.
std::string m_fanSpeedName
Current fan-control option name.
float m_full_x
The full ROI center x coordinate.
float m_startupTemp
The temperature to set after a power-on. Set to <= -999 to not use [default].
int m_full_currbin_h
The current-binning full ROI height.
std::string m_defaultFanSpeed
The default fan speed to apply after power on.
float m_ccdTemp
The current temperature, in C.
bool m_fanSpeedValid
True once the current fan-control state is known.
bool m_tempControlOnTarget
Whether or not the temperature control system is on its target temperature.
cameraConfigMap m_cameraModes
Map holding the possible camera mode configurations.
float m_full_currbin_y
The current-binning full ROI center y coordinate.
bool m_analogGainValid
True once the current analog-gain state is known.
pcf::IndiProperty m_indiP_roi_full
Property used to trigger setting the full ROI.
std::vector< std::string > m_analogGainNameLabels
Optional GUI labels for the analog-gain options.
pcf::IndiProperty m_indiP_roi_set
Property used to trigger setting the ROI.
std::vector< std::string > m_fanSpeedNameLabels
Optional GUI labels for the fan-control options.
bool m_ledState
Current status LED state.
float m_default_y
Power-on ROI center y coordinate.
float m_fps
The current FPS.
pcf::IndiProperty m_indiP_roi_bin_y
Property used to set the ROI y binning.
pcf::IndiProperty m_indiP_roi_x
Property used to set the ROI x center coordinate.
int m_default_bin_y
Power-on ROI y binning.
bool m_tempControlStatusSet
Desired state of temperature control.
float m_minFPS
The minimum FPS, used for INDI attributes.
Utilities for the C-RED 2 camera controller.
Stub EDT camera handle type used by unit tests.
#define FRAMEGRABBER_SETUP_CONFIG(cfig)
Call frameGrabberT::setupConfig with error checking for frameGrabber.
#define FRAMEGRABBER_APP_LOGIC
Call frameGrabberT::appLogic with error checking for frameGrabber.
#define FRAMEGRABBER_APP_SHUTDOWN
Call frameGrabberT::appShutdown with error checking for frameGrabber.
#define FRAMEGRABBER_LOAD_CONFIG(cfig)
Call frameGrabberT::loadConfig with error checking for frameGrabber.
#define FRAMEGRABBER_APP_STARTUP
Call frameGrabberT::appStartup with error checking for frameGrabber.
bool fullFrame
True when the ROI spans the full detector.
C-RED 2 ROI expressed as 0-based inclusive column and row limits.
#define REG_INDI_NEWPROP_NOCB(prop, propName, type)
Register a NEW INDI property with the class, with no callback.
@ OPERATING
The device is operating, other than homing.
@ NODEVICE
No device exists for the application to control.
@ CONFIGURING
The application is configuring the device.
@ ERROR
The application has encountered an error, from which it is recovering (with or without intervention)
@ READY
The device is ready for operation, but is not operating.
@ CONNECTED
The application has connected to the device or service.
@ NOTCONNECTED
The application is not connected to the device or service.
@ POWERON
The device power is on.
std::string cred2ColumnsSpec(const cred2Roi &roi)
Format the column command payload for set cropping columns.
std::string cred2CleanResponse(const std::string &response)
Strip an optional prompt and surrounding whitespace from a C-RED 2 CLI response.
int cred2ParseRange(int &firstValue, int &secondValue, const std::string &response)
Parse a raw range response such as 0-639.
int cred2RoiToCenter(float ¢erX, float ¢erY, int &width, int &height, const cred2Roi &roi, int fullWidth, int fullHeight)
Convert C-RED 2 ROI corners into a MagAO-X ROI center/size description.
int cred2ParseCropState(bool &enabled, int &startColumn, int &endColumn, int &startRow, int &endRow, const std::string &response)
Parse a raw cropping status response such as on or on:192-447:128-383.
int cred2RoiFromCenter(cred2Roi &roi, float centerX, float centerY, int width, int height, int fullWidth, int fullHeight)
Convert a MagAO-X ROI center/size description into C-RED 2 corners.
int cred2ParseFloatVector(std::vector< float > &values, const std::string &response, size_t expectedValues)
Parse a delimited list of raw numeric responses into a float vector.
bool cred2ResponseOK(const std::string &response)
Check whether a command response looks successful.
std::string cred2RowsSpec(const cred2Roi &roi)
Format the row command payload for set cropping rows.
int cred2ParseFloat(float &value, const std::string &response)
Parse a raw numeric response into a float.
int cred2ParseBool(bool &value, const std::string &response)
Parse a raw on/off response into a boolean.
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.
static constexpr logPrioT LOG_ERROR
An error has occured which the software will attempt to correct.
#define STDCAMERA_SETUP_CONFIG(cfig)
Call stdCameraT::setupConfig with error checking for stdCamera.
#define STDCAMERA_APP_LOGIC
Call stdCameraT::appLogic with error checking for stdCamera.
#define STDCAMERA_APP_STARTUP
Call stdCameraT::appStartup with error checking for stdCamera.
#define STDCAMERA_LOAD_CONFIG(cfig)
Call stdCameraT::loadConfig with error checking for stdCamera.
#define STDCAMERA_APP_SHUTDOWN
Call stdCameraT::appShutdown with error checking for stdCamera.
Structure holding the temperature values reported by the C-RED 2.
float powerboard
Power-board temperature [C].
float setpoint
Detector temperature setpoint [C].
float peltier
External TEC temperature [C].
float motherboard
Motherboard temperature [C].
int setInvalid()
Mark all temperature values invalid.
float snake
Detector temperature [C].
float frontend
Front-end temperature [C].
float heatsink
Heatsink temperature [C].
A device base class which saves telemetry.
Log entry recording the C-RED 2 detailed temperature channels.
Software CRITICAL log entry.
Log entry recording framegrabber timings.
Log entry recording stdcam stage specific status.
A simple text log, a string-type log.
#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.