From a6f15e234fa472162a42b7086cb49128aaa441f5 Mon Sep 17 00:00:00 2001 From: "Timur A. Fatkhullin" Date: Wed, 15 Jan 2025 11:37:11 +0300 Subject: [PATCH] start acquisition tunning (wait for STATUS_ARMED status before trigger snapshot) --- raptor_eagle_acqproc.cpp | 9 ++++----- raptor_eagle_ccd.cpp | 17 ++++++++++++++--- raptor_eagle_ccd.h | 3 +++ raptor_eagle_exception.h | 3 +++ 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/raptor_eagle_acqproc.cpp b/raptor_eagle_acqproc.cpp index 2b0a47e..e4c9d4b 100644 --- a/raptor_eagle_acqproc.cpp +++ b/raptor_eagle_acqproc.cpp @@ -76,10 +76,10 @@ void RaptorEagleCCD::AcquisitionProcess::start(const std::shared_ptrlogDebug("Arm grabber and wait for acquisition starting trigger (thread id: {}) ...", st.str()); + _status = STATUS_ARMED; // change to STATUS_ACQ will be made in RaptorEagleCCD::startAcquisition!!! + serverPtr->xclibApiCall(pxd_doSnap(serverPtr->_cameraUnitmap, 1, timeout.count()), std::format("pxd_doSnap({}, 1, {})", serverPtr->_cameraUnitmap, timeout.count())); @@ -303,7 +303,7 @@ void RaptorEagleCCD::AcquisitionProcess::start(const std::shared_ptrlogDebug("There is no one permanent keyword! Skip!"); } - for (auto & s : kwd_list) { + for (auto& s : kwd_list) { fits_parse_template(s.data(), card, &k_type, &status); if (status) { // ignore possible errors fits_get_errstatus(status, err_str); @@ -380,7 +380,6 @@ void RaptorEagleCCD::AcquisitionProcess::start(const std::shared_ptrlogDebug("Return buffer address {} to queue of free", (void*)_acqParams->imageBufferPtr); acqProcSptr.erase(self); - }).detach(); } @@ -417,7 +416,7 @@ std::string RaptorEagleCCD::AcquisitionProcess::status() case STATUS_IDLE: stat_str = std::format("{}", CAMERA_ATTR_CAMERA_STATUS_IDLE); break; - case STATUS_ARMED: // actually it should not be! but it presents here for debug reasons + case STATUS_ARMED: // actually it should not be! but it presents here for debug reasons stat_str = std::format("{}", CAMERA_ATTR_CAMERA_STATUS_ARMED); break; case STATUS_ACQ: { diff --git a/raptor_eagle_ccd.cpp b/raptor_eagle_ccd.cpp index abb2fd2..d22cc4a 100644 --- a/raptor_eagle_ccd.cpp +++ b/raptor_eagle_ccd.cpp @@ -185,7 +185,8 @@ RaptorEagleCCD::~RaptorEagleCCD() // wait for detached acquisition threads? if (AcquisitionProcess::acqProcSptr.size()) { - logInfo("DTOR: waiting for the end of the acquisition process {} ...", AcquisitionProcess::acqProcSptr.size() > 1 ? "threads" : "thread"); + logInfo("DTOR: waiting for the end of the acquisition process {} ...", + AcquisitionProcess::acqProcSptr.size() > 1 ? "threads" : "thread"); auto start = std::chrono::utc_clock::now(); while (AcquisitionProcess::acqProcSptr.size()) { @@ -1107,10 +1108,20 @@ void RaptorEagleCCD::startAquisition() } - std::make_shared()->start(acq_pars); + auto sptr = std::make_shared(); + sptr->start(acq_pars); // asynchronous call!!! // start acquisition here + auto start = std::chrono::utc_clock::now(); + while (sptr->_status != AcquisitionProcess::STATUS_ARMED) { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + if ((std::chrono::utc_clock::now() - start) > CAMERA_START_ACQ_TIMEOUT) { + logError("CANNOT START ACQUIRING!!!"); + throw RaptorEagleCCDError::ERROR_CANNOT_START_ACQUISITION; + } + } acq_pars->startTime = setTriggerRegisterBit(CL_TRIGGER_MODE_SNAPSHOT_BIT); + sptr->_status = AcquisitionProcess::STATUS_ACQ; int status; xclibApiCall(status = pxd_goneLive(_cameraUnitmap, 0), std::format("pxd_goneLive({}, 0)", _cameraUnitmap)); @@ -1127,7 +1138,7 @@ void RaptorEagleCCD::stopAcquisition(bool save_acq) for (auto& sptr : AcquisitionProcess::acqProcSptr) { if (sptr->_status == AcquisitionProcess::STATUS_ACQ) { sptr->stop(save_acq); - return; // the only one active acquisition process + return; // the only one active acquisition process } } diff --git a/raptor_eagle_ccd.h b/raptor_eagle_ccd.h index c5f6f65..fd3f407 100644 --- a/raptor_eagle_ccd.h +++ b/raptor_eagle_ccd.h @@ -71,6 +71,9 @@ public: std::chrono::milliseconds(1000)}; + // wait timeout to start acquisition (deadlock?!!) + static constexpr std::chrono::milliseconds CAMERA_START_ACQ_TIMEOUT{1000}; // 1 second + // additive constant to timeout for capture process (see pxd_doSnap XCLIB function) // this constant will be added to exposure to compute actual timeout static constexpr std::chrono::milliseconds CAMERA_CAPTURE_TIMEOUT_ADD_CONSTANT{240000}; // 4 mins diff --git a/raptor_eagle_exception.h b/raptor_eagle_exception.h index 54bca79..75c1c71 100644 --- a/raptor_eagle_exception.h +++ b/raptor_eagle_exception.h @@ -16,6 +16,7 @@ enum class RaptorEagleCCDError : int { ERROR_CANNOT_RESET_FPGA, ERROR_EXT_TRIGGER_MODE, ERROR_ACQUISITION_IN_PROGRESS, + ERROR_CANNOT_START_ACQUISITION, ERROR_INVALID_PATH, ERROR_INSUFFICIENT_FILESYSTEM_PERMISSIONS, ERROR_NO_FREE_BUFFER @@ -65,6 +66,8 @@ struct RaptorEagleCCDErrorCategory : std::error_category { return "try to use software trigger while external trigger mode is enabled"; case RaptorEagleCCDError::ERROR_ACQUISITION_IN_PROGRESS: return "acquisition is in progress"; + case RaptorEagleCCDError::ERROR_CANNOT_START_ACQUISITION: + return "cannot start acquisition"; case RaptorEagleCCDError::ERROR_INVALID_PATH: return "invalid filesystem path"; case RaptorEagleCCDError::ERROR_INSUFFICIENT_FILESYSTEM_PERMISSIONS: