...
This commit is contained in:
parent
4dd6893674
commit
3b1c1a3e72
@ -16,7 +16,8 @@ set(RAPTOR_EAGLEV_LIB raptor_eaglev)
|
||||
add_library(${RAPTOR_EAGLEV_LIB} SHARED
|
||||
raptor_eagle_ccd.h raptor_eagle_ccd.cpp
|
||||
raptor_eagle_cameralink.h
|
||||
raptor_eagle_exception.h)
|
||||
raptor_eagle_exception.h
|
||||
raptor_eagle_acqproc.cpp)
|
||||
|
||||
# to activate spdlog-library support in ADC-library
|
||||
target_compile_definitions(${RAPTOR_EAGLEV_LIB} PRIVATE USE_SPDLOG_LIBRARY)
|
||||
|
||||
88
raptor_eagle_acqproc.cpp
Normal file
88
raptor_eagle_acqproc.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
#include <cmath>
|
||||
#include "raptor_eagle_ccd.h"
|
||||
|
||||
|
||||
/*******************************************************************************/
|
||||
/* ======= RaptorEagleCCD::AcquisitionProcess CLASS IMPLEMENTATION ======= */
|
||||
/*******************************************************************************/
|
||||
|
||||
|
||||
RaptorEagleCCD::AcquisitionProcess::AcquisitionProcess(RaptorEagleCCD* manager) : _manager(manager)
|
||||
{
|
||||
std::stringstream st;
|
||||
st << std::this_thread::get_id();
|
||||
_manager->logDebug("Create acquisition process (thread id: {})", st.str());
|
||||
}
|
||||
|
||||
|
||||
RaptorEagleCCD::AcquisitionProcess::~AcquisitionProcess()
|
||||
{
|
||||
std::stringstream st;
|
||||
st << std::this_thread::get_id();
|
||||
_manager->logDebug("Delete acquisition process (thread id: {})", st.str());
|
||||
}
|
||||
|
||||
|
||||
void RaptorEagleCCD::AcquisitionProcess::start(const std::shared_ptr<acq_params_t>& params)
|
||||
{
|
||||
// _acqParams = std::move(params);
|
||||
_acqParams = params;
|
||||
_acqParams->abortTime = std::chrono::utc_clock::time_point(); // to ensure the time point is in past
|
||||
|
||||
_snapAndCopyFuture = std::async(std::launch::async, [self = shared_from_this(), this]() {
|
||||
std::chrono::milliseconds timeout =
|
||||
CAMERA_CAPTURE_TIMEOUT_ADD_CONSTANT +
|
||||
std::chrono::milliseconds(static_cast<std::chrono::milliseconds::rep>(_acqParams->expTime * 1000));
|
||||
|
||||
static char color_space[] = "Grey";
|
||||
std::stringstream st;
|
||||
st << std::this_thread::get_id();
|
||||
|
||||
_manager->logDebug("Arm grabber and wait for acquisition starting trigger (thread id: {}) ...", st.str());
|
||||
|
||||
_manager->xclibApiCall(pxd_doSnap(_manager->_cameraUnitmap, 1, timeout.count()),
|
||||
std::format("pxd_doSnap({},1,{})", _manager->_cameraUnitmap, timeout.count()));
|
||||
|
||||
_manager->logDebug("Capture is finished (thread id: {})!", st.str());
|
||||
|
||||
_manager->logDebug("Copy image from grabber to buffer (thread id: {}) ...", st.str());
|
||||
|
||||
size_t npix = _acqParams->roiWidth * _acqParams->roiHeight;
|
||||
|
||||
_imageBufferRows = static_cast<size_t>(std::ceil(npix / _manager->_dimCCD[0]));
|
||||
size_t sz = _imageBufferRows * npix;
|
||||
|
||||
if (_imageBufferSize < sz) {
|
||||
_imageBufferSize = sz;
|
||||
_imageBuffer.reset(new ushort[sz]); // may thow std::bad_alloc here!
|
||||
}
|
||||
|
||||
auto log_str = std::format("pxd_readushort({}, 1, 0, 0, -1, {}, {}, {}, \"{}\")", _manager->_cameraUnitmap,
|
||||
_imageBufferRows, (void*)_imageBuffer.get(), _imageBufferSize, color_space);
|
||||
|
||||
_manager->xclibApiCall(pxd_readushort(_manager->_cameraUnitmap, 1, 0, 0, -1, _imageBufferRows,
|
||||
_imageBuffer.get(), _imageBufferSize, (char*)color_space),
|
||||
log_str);
|
||||
|
||||
isAcqInProgress = false;
|
||||
|
||||
// save to FITS file
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void RaptorEagleCCD::AcquisitionProcess::stop(bool save)
|
||||
{
|
||||
if (isAcqInProgress) {
|
||||
_manager->logInfo("Abort current acquisition process!");
|
||||
|
||||
auto bytes = _manager->readRegisters({0xD4}); // trigger mode register
|
||||
bytes[0] |= CL_ABORT_CURRENT_EXP; // set abort acquisition bit
|
||||
_manager->writeRegisters({0xD4}, bytes);
|
||||
|
||||
_acqParams->abortTime = std::chrono::utc_clock::now();
|
||||
_acqParams->saveInAbort = save;
|
||||
} else {
|
||||
_manager->logWarn("There was no active acquisition process! Ignore!");
|
||||
}
|
||||
}
|
||||
@ -108,6 +108,9 @@ static constexpr unsigned char CL_TRIGGER_MODE_FFR = 0b00000110;
|
||||
static constexpr unsigned char CL_TRIGGER_MODE_ITR = 0b00000100;
|
||||
static constexpr unsigned char CL_TRIGGER_MODE_SNAPSHOT = 0; // just clear all bits
|
||||
|
||||
static constexpr unsigned char CL_ABORT_CURRENT_EXP = 0b00001000;
|
||||
|
||||
|
||||
/* SETUP CONTROL VALUES */
|
||||
|
||||
// shutter
|
||||
|
||||
@ -751,47 +751,109 @@ void RaptorEagleCCD::getFPGAVersion()
|
||||
|
||||
/* ACQUISITION PROCESS */
|
||||
|
||||
void RaptorEagleCCD::startAquisition(acq_params_t acq_pars)
|
||||
void RaptorEagleCCD::startAquisition()
|
||||
{
|
||||
acq_pars.startTime = std::chrono::utc_clock::now();
|
||||
std::chrono::milliseconds snap_tm =
|
||||
CAMERA_CAPTURE_TIMEOUT_ADD_CONSTANT +
|
||||
std::chrono::milliseconds(static_cast<std::chrono::milliseconds::rep>(acq_pars.expTime * 1000));
|
||||
// if (_isAcqInProgress) {
|
||||
if (AcquisitionProcess::isAcqInProgress) {
|
||||
logError("Acquisition is in progress! Exit!");
|
||||
throw std::error_code(RaptorEagleCCDError::ERROR_ACQUISITION_IN_PROGRESS);
|
||||
}
|
||||
|
||||
_doSnapAndCopyFuture = std::async(
|
||||
std::launch::async,
|
||||
[acq_pars = std::move(acq_pars), this](std::chrono::milliseconds timeout) mutable {
|
||||
static char color_space[] = "Grey";
|
||||
std::stringstream st;
|
||||
st << std::this_thread::get_id();
|
||||
auto bytes = readRegisters({0xD4}); // trigger mode register
|
||||
std::bitset<8> bits(bytes[0]);
|
||||
|
||||
logDebug("Arm grabber and wait for acquisition start trigger (thread id: {}) ...", st.str());
|
||||
if (bits.test(CL_TRIGGER_MODE_EXT_TRIGGER_BIT)) {
|
||||
logError("External trigger mode is set! Nothing to do, exit!");
|
||||
throw std::error_code(RaptorEagleCCDError::ERROR_EXT_TRIGGER_MODE);
|
||||
}
|
||||
|
||||
xclibApiCall(pxd_doSnap(_cameraUnitmap, 1, timeout.count()),
|
||||
std::format("pxd_doSnap({},1,{})", _cameraUnitmap, timeout.count()));
|
||||
|
||||
logDebug("Capture is finished (thread id: {})!", st.str());
|
||||
logInfo("Start acquisition process");
|
||||
|
||||
logDebug("Copy image from grabber to buffer (thread id: {}) ...", st.str());
|
||||
|
||||
size_t npix = acq_pars.roiWidth * acq_pars.roiHeight;
|
||||
auto acq_pars = std::make_shared<acq_params_t>(acq_params_t({
|
||||
.startTime = std::chrono::utc_clock::time_point(),
|
||||
.abortTime = std::chrono::utc_clock::time_point(),
|
||||
.saveInAbort = false,
|
||||
.expTime = (*this)[CAMERA_ATTR_EXPTIME],
|
||||
.roiStartX = (*this)[CAMERA_ATTR_ROI_STARTX],
|
||||
.roiStartY = (*this)[CAMERA_ATTR_ROI_STARTY],
|
||||
.roiWidth = (*this)[CAMERA_ATTR_ROI_WIDTH],
|
||||
.roiHeight = (*this)[CAMERA_ATTR_ROI_HEIGHT],
|
||||
.binX = (*this)[CAMERA_ATTR_XBIN],
|
||||
.binY = (*this)[CAMERA_ATTR_YBIN],
|
||||
.readRate = (*this)[CAMERA_ATTR_READ_RATE],
|
||||
.readMode = (*this)[CAMERA_ATTR_READ_MODE],
|
||||
.filename = (*this)[CAMERA_ATTR_FITS_FILENAME],
|
||||
.templateFilename = (*this)[CAMERA_ATTR_FITS_TEMPLATE],
|
||||
.permanentKeywords = _permanentFitsKeywords, // copy
|
||||
.currentKeywords = std::move(_currentFitsKeywords) // move!!!
|
||||
|
||||
acq_pars.imageBufferRows = static_cast<size_t>(std::ceil(npix / _dimCCD[0]));
|
||||
size_t sz = acq_pars.imageBufferRows * npix;
|
||||
}));
|
||||
|
||||
if (acq_pars.imageBufferSize < sz) {
|
||||
acq_pars.imageBufferSize = sz;
|
||||
acq_pars.imageBuffer.reset(new ushort[sz]); // may thow std::bad_alloc here!
|
||||
}
|
||||
// arm grabber
|
||||
std::make_shared<AcquisitionProcess>(this)->start(acq_pars);
|
||||
|
||||
auto log_str =
|
||||
std::format("pxd_readushort({}, 1, 0, 0, -1, {}, {}, {}, {})", _cameraUnitmap, acq_pars.imageBufferRows,
|
||||
(void*)acq_pars.imageBuffer.get(), acq_pars.imageBufferSize, (void*)color_space);
|
||||
xclibApiCall(pxd_readushort(_cameraUnitmap, 1, 0, 0, -1, acq_pars.imageBufferRows,
|
||||
acq_pars.imageBuffer.get(), acq_pars.imageBufferSize, (char*)color_space),
|
||||
log_str);
|
||||
},
|
||||
std::move(snap_tm));
|
||||
acq_pars->startTime = std::chrono::utc_clock::now();
|
||||
bits.set(CL_TRIGGER_MODE_SNAPSHOT_BIT); // start snapshot
|
||||
|
||||
|
||||
// _doSnapAndCopyFuture = std::async(std::launch::async, [acq_pars = std::move(acq_pars), this]() mutable {
|
||||
// std::chrono::milliseconds timeout =
|
||||
// CAMERA_CAPTURE_TIMEOUT_ADD_CONSTANT +
|
||||
// std::chrono::milliseconds(static_cast<std::chrono::milliseconds::rep>(acq_pars.expTime * 1000));
|
||||
|
||||
// static char color_space[] = "Grey";
|
||||
// std::stringstream st;
|
||||
// st << std::this_thread::get_id();
|
||||
|
||||
// logDebug("Arm grabber and wait for acquisition start trigger (thread id: {}) ...", st.str());
|
||||
|
||||
// xclibApiCall(pxd_doSnap(_cameraUnitmap, 1, timeout.count()),
|
||||
// std::format("pxd_doSnap({},1,{})", _cameraUnitmap, timeout.count()));
|
||||
|
||||
// logDebug("Capture is finished (thread id: {})!", st.str());
|
||||
|
||||
// logDebug("Copy image from grabber to buffer (thread id: {}) ...", st.str());
|
||||
|
||||
// size_t npix = acq_pars.roiWidth * acq_pars.roiHeight;
|
||||
|
||||
// acq_pars.imageBufferRows = static_cast<size_t>(std::ceil(npix / _dimCCD[0]));
|
||||
// size_t sz = acq_pars.imageBufferRows * npix;
|
||||
|
||||
// if (acq_pars.imageBufferSize < sz) {
|
||||
// acq_pars.imageBufferSize = sz;
|
||||
// acq_pars.imageBuffer.reset(new ushort[sz]); // may thow std::bad_alloc here!
|
||||
// }
|
||||
|
||||
// auto log_str =
|
||||
// std::format("pxd_readushort({}, 1, 0, 0, -1, {}, {}, {}, \"{}\")", _cameraUnitmap,
|
||||
// acq_pars.imageBufferRows,
|
||||
// (void*)acq_pars.imageBuffer.get(), acq_pars.imageBufferSize, color_space);
|
||||
// xclibApiCall(pxd_readushort(_cameraUnitmap, 1, 0, 0, -1, acq_pars.imageBufferRows,
|
||||
// acq_pars.imageBuffer.get(),
|
||||
// acq_pars.imageBufferSize, (char*)color_space),
|
||||
// log_str);
|
||||
// });
|
||||
|
||||
// logInfo("Start acquisition process");
|
||||
|
||||
// _isAcqInProgress = true;
|
||||
// acq_pars.startTime = std::chrono::utc_clock::now();
|
||||
// bits.set(CL_TRIGGER_MODE_SNAPSHOT_BIT); // start snapshot
|
||||
}
|
||||
|
||||
|
||||
void RaptorEagleCCD::stopAcquisition()
|
||||
{
|
||||
if (_isAcqInProgress) {
|
||||
logInfo("Abort current acquisition process!");
|
||||
auto bytes = readRegisters({0xD4}); // trigger mode register
|
||||
bytes[0] |= CL_ABORT_CURRENT_EXP; // set abort acquisition bit
|
||||
writeRegisters({0xD4}, bytes);
|
||||
} else {
|
||||
logWarn("There was no active acquisition process! Ignore!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1585,7 +1647,10 @@ void RaptorEagleCCD::initAttrComm()
|
||||
logWarn("Invalid trigger mode! Set it to {}!", CAMERA_ATTR_TRIGGER_MODE_SNAPSHOT);
|
||||
}
|
||||
|
||||
writeRegisters({0xD4}, {bits});
|
||||
// snapshot mode is self-clearing bit so activate it directly in 'startAcquision' method
|
||||
if (mode != CAMERA_ATTR_TRIGGER_MODE_SNAPSHOT) {
|
||||
writeRegisters({0xD4}, {bits});
|
||||
}
|
||||
|
||||
logDebug("Trigger mode bits are set to 0b{:08b}", bits);
|
||||
});
|
||||
|
||||
@ -144,8 +144,9 @@ private:
|
||||
typedef std::vector<unsigned char> byte_seq_t;
|
||||
|
||||
struct acq_params_t {
|
||||
uint16_t ccdDim[2];
|
||||
std::chrono::utc_clock::time_point startTime;
|
||||
std::chrono::utc_clock::time_point abortTime;
|
||||
bool saveInAbort;
|
||||
double expTime; // in seconds
|
||||
uint16_t roiStartX;
|
||||
uint16_t roiStartY;
|
||||
@ -160,9 +161,33 @@ private:
|
||||
std::vector<std::string> permanentKeywords;
|
||||
std::vector<std::string> currentKeywords;
|
||||
|
||||
std::unique_ptr<ushort> imageBuffer;
|
||||
size_t imageBufferSize;
|
||||
size_t imageBufferRows;
|
||||
// std::unique_ptr<ushort> imageBuffer;
|
||||
// size_t imageBufferSize;
|
||||
// size_t imageBufferRows;
|
||||
};
|
||||
|
||||
class AcquisitionProcess : public std::enable_shared_from_this<AcquisitionProcess>
|
||||
{
|
||||
friend class RaptorEagleCCD;
|
||||
|
||||
public:
|
||||
AcquisitionProcess(RaptorEagleCCD*);
|
||||
~AcquisitionProcess();
|
||||
|
||||
void start(const std::shared_ptr<acq_params_t>& params); // asynchronous method!
|
||||
void stop(bool save = true);
|
||||
|
||||
private:
|
||||
inline static std::atomic_bool isAcqInProgress = false;
|
||||
|
||||
RaptorEagleCCD* _manager;
|
||||
std::shared_ptr<acq_params_t> _acqParams;
|
||||
std::unique_ptr<ushort> _imageBuffer;
|
||||
size_t _imageBufferSize;
|
||||
size_t _imageBufferRows;
|
||||
|
||||
std::future<void> _snapAndCopyFuture;
|
||||
std::future<void> _saveFitsFileFuture;
|
||||
};
|
||||
|
||||
std::string _epixFmtVideoFilename;
|
||||
@ -270,7 +295,7 @@ private:
|
||||
void getFPGAVersion();
|
||||
|
||||
// acquisition process methods
|
||||
void startAquisition(acq_params_t);
|
||||
void startAquisition();
|
||||
void stopAcquisition();
|
||||
|
||||
// logging helper methods
|
||||
|
||||
@ -12,7 +12,9 @@ enum class RaptorEagleCCDError : int {
|
||||
ERROR_CAMLINK_WRITE,
|
||||
ERROR_CANNOT_INIT_CAMERA,
|
||||
ERROR_CANNOT_RESET_MICRO,
|
||||
ERROR_CANNOT_RESET_FPGA
|
||||
ERROR_CANNOT_RESET_FPGA,
|
||||
ERROR_EXT_TRIGGER_MODE,
|
||||
ERROR_ACQUISITION_IN_PROGRESS
|
||||
};
|
||||
|
||||
|
||||
@ -53,6 +55,10 @@ struct RaptorEagleCCDErrorCategory : std::error_category {
|
||||
return "cannot reset camera microcontroller";
|
||||
case RaptorEagleCCDError::ERROR_CANNOT_RESET_FPGA:
|
||||
return "cannot reset FPGA board";
|
||||
case RaptorEagleCCDError::ERROR_EXT_TRIGGER_MODE:
|
||||
return "try to use software trigger while external trigger mode is enabled";
|
||||
case RaptorEagleCCDError::ERROR_ACQUISITION_IN_PROGRESS:
|
||||
return "acquisition is in progress";
|
||||
default:
|
||||
return "UNKNOWN ERROR";
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user