Commit f7fa1053 authored by Eric Dejouhanet's avatar Eric Dejouhanet Committed by Jasem Mutlaq

Fix the focus state notification

parent fafbf12e
Pipeline #42530 passed with stage
in 6 minutes and 11 seconds
......@@ -49,19 +49,109 @@ void TestEkosFocus::cleanup()
}
void TestEkosFocus::testCaptureStates()
{
// Wait for Focus to come up, switch to Focus tab
KTRY_FOCUS_SHOW();
// Sync high on meridian to avoid issues with CCD Simulator
KTRY_FOCUS_SYNC(60.0);
// Pre-configure steps
KTRY_FOCUS_MOVETO(40000);
// Prepare to detect state change
QList <Ekos::FocusState> state_list;
auto state_handler = connect(Ekos::Manager::Instance()->focusModule(), &Ekos::Focus::newStatus, this, [&](Ekos::FocusState s) {
state_list.append(s);
});
QVERIFY(state_handler);
// Configure some fields, capture, check states
KTRY_FOCUS_CONFIGURE("SEP", "Iterative", 0.0, 100.0, 3.0);
KTRY_FOCUS_DETECT(2, 1, 99);
QTRY_COMPARE_WITH_TIMEOUT(state_list.count(), 2, 5000);
QCOMPARE(state_list[0], Ekos::FocusState::FOCUS_PROGRESS);
QCOMPARE(state_list[1], Ekos::FocusState::FOCUS_IDLE);
state_list.clear();
// Move step value, expect no capture
KTRY_FOCUS_CONFIGURE("SEP", "Iterative", 0.0, 100.0, 3.0);
KTRY_FOCUS_MOVETO(43210);
QTest::qWait(1000);
QCOMPARE(state_list.count(), 0);
KTRY_FOCUS_GADGET(QPushButton, startLoopB);
KTRY_FOCUS_GADGET(QPushButton, stopFocusB);
// Loop captures, abort, check states
KTRY_FOCUS_CONFIGURE("SEP", "Iterative", 0.0, 100.0, 3.0);
KTRY_FOCUS_CLICK(startLoopB);
QTRY_VERIFY_WITH_TIMEOUT(state_list.count() >= 1, 5000);
KTRY_FOCUS_CLICK(stopFocusB);
QTRY_VERIFY_WITH_TIMEOUT(state_list.count() >= 4, 5000);
QCOMPARE(state_list[0], Ekos::FocusState::FOCUS_FRAMING);
QCOMPARE(state_list[1], Ekos::FocusState::FOCUS_PROGRESS);
QCOMPARE(state_list[2], Ekos::FocusState::FOCUS_ABORTED);
QCOMPARE(state_list[3], Ekos::FocusState::FOCUS_IDLE);
state_list.clear();
KTRY_FOCUS_GADGET(QCheckBox, useAutoStar);
KTRY_FOCUS_GADGET(QPushButton, resetFrameB);
QWARN("This test does not wait for the hardcoded timeout to select a star.");
// Use successful automatic star selection (not full-field), capture, check states
KTRY_FOCUS_CONFIGURE("SEP", "Iterative", 0.0, 0.0, 3.0);
useAutoStar->setCheckState(Qt::CheckState::Checked);
KTRY_FOCUS_DETECT(2, 1, 99);
QTRY_VERIFY_WITH_TIMEOUT(state_list.count() >= 2, 5000);
QTRY_VERIFY_WITH_TIMEOUT(!stopFocusB->isEnabled(), 1000);
KTRY_FOCUS_CLICK(resetFrameB);
QCOMPARE(state_list[0], Ekos::FocusState::FOCUS_PROGRESS);
QCOMPARE(state_list[1], Ekos::FocusState::FOCUS_IDLE);
useAutoStar->setCheckState(Qt::CheckState::Unchecked);
state_list.clear();
// Use unsuccessful automatic star selection, capture, check states
KTRY_FOCUS_CONFIGURE("SEP", "Iterative", 0.0, 0.0, 3.0);
useAutoStar->setCheckState(Qt::CheckState::Checked);
KTRY_FOCUS_DETECT(0.01, 1, 1);
QTRY_VERIFY_WITH_TIMEOUT(state_list.count() >= 2, 5000);
QTRY_VERIFY_WITH_TIMEOUT(!stopFocusB->isEnabled(), 1000);
KTRY_FOCUS_CLICK(resetFrameB);
QCOMPARE(state_list[0], Ekos::FocusState::FOCUS_PROGRESS);
QCOMPARE(state_list[1], Ekos::FocusState::FOCUS_WAITING);
useAutoStar->setCheckState(Qt::CheckState::Unchecked);
state_list.clear();
disconnect(state_handler);
}
void TestEkosFocus::testDuplicateFocusRequest()
{
// Wait for Focus to come up, switch to Focus tab
KTRY_FOCUS_SHOW();
// Sync high on meridian to avoid issues with CCD Simulator
KTRY_FOCUS_SYNC(60.0);
// Configure a fast autofocus, pre-set to near-optimal 38500 steps
KTRY_FOCUS_MOVETO(40000);
KTRY_FOCUS_CONFIGURE("SEP", "Iterative", 0.0, 0.0, 3.0);
KTRY_FOCUS_EXPOSURE(1, 99);
KTRY_FOCUS_GADGET(QPushButton, startFocusB);
KTRY_FOCUS_GADGET(QPushButton, stopFocusB);
QTRY_VERIFY_WITH_TIMEOUT(startFocusB->isEnabled(), 1000);
QTRY_VERIFY_WITH_TIMEOUT(!stopFocusB->isEnabled(), 1000);
QCOMPARE(Ekos::Manager::Instance()->focusModule()->status(), Ekos::FOCUS_IDLE);
KTRY_FOCUS_DETECT(2, 1);
// Prepare to detect the beginning of the autofocus_procedure
volatile bool autofocus_started = false;
connect(Ekos::Manager::Instance()->focusModule(), &Ekos::Focus::autofocusStarting, this, [&]() { autofocus_started = true; });
auto startup_handler = connect(Ekos::Manager::Instance()->focusModule(), &Ekos::Focus::autofocusStarting, this, [&]() {
autofocus_started = true;
});
QVERIFY(startup_handler);
// If we click the autofocus button, we receive a signal that the procedure starts, the state change and the button is disabled
KTRY_FOCUS_CLICK(startFocusB);
......@@ -78,7 +168,303 @@ void TestEkosFocus::testDuplicateFocusRequest()
// Stop the running autofocus
KTRY_FOCUS_CLICK(stopFocusB);
QTRY_COMPARE_WITH_TIMEOUT(Ekos::Manager::Instance()->focusModule()->status(), Ekos::FOCUS_ABORTED, 5000);
QTest::qWait(500);
disconnect(startup_handler);
}
void TestEkosFocus::testAutofocusSignalEmission()
{
// Wait for Focus to come up, switch to Focus tab
KTRY_FOCUS_SHOW();
// Sync high on meridian to avoid issues with CCD Simulator
KTRY_FOCUS_SYNC(60.0);
// Configure a fast autofocus, pre-set to near-optimal 38500 steps
KTRY_FOCUS_MOVETO(40000);
KTRY_FOCUS_CONFIGURE("SEP", "Iterative", 0.0, 100.0, 3.0);
KTRY_FOCUS_EXPOSURE(1, 99);
KTRY_FOCUS_GADGET(QPushButton, startFocusB);
KTRY_FOCUS_GADGET(QPushButton, stopFocusB);
QTRY_VERIFY_WITH_TIMEOUT(startFocusB->isEnabled(), 1000);
QTRY_VERIFY_WITH_TIMEOUT(!stopFocusB->isEnabled(), 1000);
// Prepare to detect the beginning of the autofocus_procedure
volatile bool autofocus_started = false;
auto startup_handler = connect(Ekos::Manager::Instance()->focusModule(), &Ekos::Focus::autofocusStarting, this, [&]() {
autofocus_started = true;
});
QVERIFY(startup_handler);
// Prepare to restart the autofocus procedure immediately when it finishes
volatile bool ran_once = false;
volatile bool autofocus_complete = false;
auto completion_handler = connect(Ekos::Manager::Instance()->focusModule(), &Ekos::Focus::autofocusComplete, this, [&]() {
autofocus_complete = true;
autofocus_started = false;
if (!ran_once)
{
Ekos::Manager::Instance()->focusModule()->start();
ran_once = true;
}
});
QVERIFY(completion_handler);
// Run the autofocus, wait for the completion signal and restart a second one immediately
QVERIFY(!autofocus_started);
QVERIFY(!autofocus_complete);
KTRY_FOCUS_CLICK(startFocusB);
QTRY_VERIFY_WITH_TIMEOUT(autofocus_started, 500);
QTRY_VERIFY_WITH_TIMEOUT(autofocus_complete, 30000);
// Wait for the second run to finish
autofocus_complete = false;
QTRY_VERIFY_WITH_TIMEOUT(autofocus_complete, 30000);
// No other autofocus started after that
QVERIFY(!autofocus_started);
// Disconnect signals
disconnect(startup_handler);
disconnect(completion_handler);
}
void TestEkosFocus::testFocusAbort()
{
// Wait for Focus to come up, switch to Focus tab
KTRY_FOCUS_SHOW();
// Sync high on meridian to avoid issues with CCD Simulator
KTRY_FOCUS_SYNC(60.0);
// Configure a fast autofocus, pre-set to near-optimal 38500 steps
KTRY_FOCUS_MOVETO(40000);
KTRY_FOCUS_CONFIGURE("SEP", "Iterative", 0.0, 100.0, 3.0);
KTRY_FOCUS_EXPOSURE(1, 99);
KTRY_FOCUS_GADGET(QPushButton, startFocusB);
KTRY_FOCUS_GADGET(QPushButton, stopFocusB);
QTRY_VERIFY_WITH_TIMEOUT(startFocusB->isEnabled(), 1000);
QTRY_VERIFY_WITH_TIMEOUT(!stopFocusB->isEnabled(), 1000);
// Prepare to detect the beginning of the autofocus_procedure
volatile bool autofocus_started = false;
auto startup_handler = connect(Ekos::Manager::Instance()->focusModule(), &Ekos::Focus::autofocusStarting, this, [&]() {
autofocus_started = true;
});
QVERIFY(startup_handler);
// Prepare to detect the end of the autofocus_procedure
volatile bool autofocus_completed = false;
auto completion_handler = connect(Ekos::Manager::Instance()->focusModule(), &Ekos::Focus::autofocusComplete, this, [&]() {
autofocus_completed = true;
autofocus_started = false;
});
QVERIFY(completion_handler);
// Prepare to restart the autofocus procedure immediately when it finishes
volatile bool ran_once = false;
volatile bool autofocus_aborted = false;
auto abort_handler = connect(Ekos::Manager::Instance()->focusModule(), &Ekos::Focus::autofocusAborted, this, [&]() {
autofocus_aborted = true;
autofocus_started = false;
if (!ran_once)
{
Ekos::Manager::Instance()->focusModule()->start();
ran_once = true;
}
});
QVERIFY(abort_handler);
// Run the autofocus, don't wait for the completion signal, abort it and restart a second one immediately
QVERIFY(!autofocus_started);
QVERIFY(!autofocus_aborted);
QVERIFY(!autofocus_completed);
KTRY_FOCUS_CLICK(startFocusB);
QTRY_VERIFY_WITH_TIMEOUT(autofocus_started, 500);
KTRY_FOCUS_CLICK(stopFocusB);
QTRY_VERIFY_WITH_TIMEOUT(autofocus_aborted, 1000);
// Wait for the second run to finish
QTRY_VERIFY_WITH_TIMEOUT(autofocus_started, 500);
QTRY_VERIFY_WITH_TIMEOUT(autofocus_completed, 30000);
// No other autofocus started after that
QVERIFY(!autofocus_started);
// Disconnect signals
disconnect(startup_handler);
disconnect(completion_handler);
disconnect(abort_handler);
}
void TestEkosFocus::testGuidingSuspend()
{
// Wait for Focus to come up, switch to Focus tab
KTRY_FOCUS_SHOW();
// Sync high on meridian to avoid issues with CCD Simulator
KTRY_FOCUS_SYNC(60.0);
// Configure a fast autofocus
KTRY_FOCUS_MOVETO(40000);
KTRY_FOCUS_CONFIGURE("SEP", "Iterative", 0.0, 100.0, 3);
KTRY_FOCUS_EXPOSURE(1, 99);
KTRY_FOCUS_GADGET(QPushButton, startFocusB);
KTRY_FOCUS_GADGET(QPushButton, stopFocusB);
QTRY_VERIFY_WITH_TIMEOUT(startFocusB->isEnabled(), 1000);
QTRY_VERIFY_WITH_TIMEOUT(!stopFocusB->isEnabled(), 1000);
// Prepare to detect the beginning of the autofocus_procedure
volatile bool autofocus_started = false;
auto startup_handler = connect(Ekos::Manager::Instance()->focusModule(), &Ekos::Focus::autofocusStarting, this, [&]() {
autofocus_started = true;
});
QVERIFY(startup_handler);
// Prepare to detect the failure of the autofocus procedure
volatile bool autofocus_aborted = false;
auto abort_handler = connect(Ekos::Manager::Instance()->focusModule(), &Ekos::Focus::autofocusAborted, this, [&]() {
autofocus_aborted = true;
autofocus_started = false;
});
QVERIFY(abort_handler);
// Prepare to detect the end of the autofocus_procedure
volatile bool autofocus_completed = false;
auto completion_handler = connect(Ekos::Manager::Instance()->focusModule(), &Ekos::Focus::autofocusComplete, this, [&]() {
autofocus_completed = true;
autofocus_started = false;
});
QVERIFY(completion_handler);
// Prepare to detect guiding suspending
volatile bool guiding_suspended = false;
auto suspend_handler = connect(Ekos::Manager::Instance()->focusModule(), &Ekos::Focus::suspendGuiding, this, [&]() {
guiding_suspended = true;
});
QVERIFY(suspend_handler);
// Prepare to detect guiding suspending
auto resume_handler = connect(Ekos::Manager::Instance()->focusModule(), &Ekos::Focus::resumeGuiding, this, [&]() {
guiding_suspended = false;
});
QVERIFY(resume_handler);
KTRY_FOCUS_GADGET(QCheckBox, suspendGuideCheck);
// Abort the autofocus with guiding set to suspend, guiding will be required to suspend, then required to resume
suspendGuideCheck->setCheckState(Qt::CheckState::Checked);
QVERIFY(!autofocus_started);
QVERIFY(!autofocus_aborted);
QVERIFY(!autofocus_completed);
QVERIFY(!guiding_suspended);
KTRY_FOCUS_CLICK(startFocusB);
QTRY_VERIFY_WITH_TIMEOUT(autofocus_started, 500);
QVERIFY(guiding_suspended);
Ekos::Manager::Instance()->focusModule()->abort();
QTRY_VERIFY_WITH_TIMEOUT(autofocus_aborted, 5000);
QVERIFY(!guiding_suspended);
// Run the autofocus to completion with guiding set to suspend, guiding will be required to suspend, then required to resume
autofocus_started = autofocus_aborted = false;
KTRY_FOCUS_CLICK(startFocusB);
QTRY_VERIFY_WITH_TIMEOUT(autofocus_started, 500);
QVERIFY(guiding_suspended);
QTRY_VERIFY_WITH_TIMEOUT(autofocus_completed, 30000);
QVERIFY(!guiding_suspended);
// No other autofocus started after that
QVERIFY(!autofocus_started);
// Abort the autofocus with guiding set to continue, no guiding signal will be emitted
suspendGuideCheck->setCheckState(Qt::CheckState::Unchecked);
autofocus_started = autofocus_aborted = autofocus_completed = guiding_suspended = false;
KTRY_FOCUS_CLICK(startFocusB);
QTRY_VERIFY_WITH_TIMEOUT(autofocus_started, 500);
QVERIFY(!guiding_suspended);
Ekos::Manager::Instance()->focusModule()->abort();
QTRY_VERIFY_WITH_TIMEOUT(autofocus_aborted, 5000);
QVERIFY(!guiding_suspended);
// Run the autofocus to completion with guiding set to continue, no guiding signal will be emitted
autofocus_started = autofocus_aborted = false;
KTRY_FOCUS_CLICK(startFocusB);
QTRY_VERIFY_WITH_TIMEOUT(autofocus_started, 500);
QVERIFY(!guiding_suspended);
QTRY_VERIFY_WITH_TIMEOUT(autofocus_completed, 30000);
QVERIFY(!guiding_suspended);
// No other autofocus started after that
QVERIFY(!autofocus_started);
// Disconnect signals
disconnect(startup_handler);
disconnect(completion_handler);
disconnect(abort_handler);
disconnect(suspend_handler);
disconnect(resume_handler);
}
void TestEkosFocus::testFocusFailure()
{
// Wait for Focus to come up, switch to Focus tab
KTRY_FOCUS_SHOW();
// Sync high on meridian to avoid issues with CCD Simulator
KTRY_FOCUS_SYNC(60.0);
// Configure a failing autofocus - small gain, small exposure, small frame filter
KTRY_FOCUS_MOVETO(10000);
KTRY_FOCUS_CONFIGURE("SEP", "Iterative", 0.0, 1.0, 0.1);
KTRY_FOCUS_EXPOSURE(0.01, 1);
KTRY_FOCUS_GADGET(QPushButton, startFocusB);
KTRY_FOCUS_GADGET(QPushButton, stopFocusB);
QTRY_VERIFY_WITH_TIMEOUT(startFocusB->isEnabled(), 1000);
QTRY_VERIFY_WITH_TIMEOUT(!stopFocusB->isEnabled(), 1000);
// Prepare to detect the beginning of the autofocus_procedure
volatile bool autofocus_started = false;
auto startup_handler = connect(Ekos::Manager::Instance()->focusModule(), &Ekos::Focus::autofocusStarting, this, [&]() {
autofocus_started = true;
});
QVERIFY(startup_handler);
// Prepare to detect the end of the autofocus_procedure
volatile bool autofocus_completed = false;
auto completion_handler = connect(Ekos::Manager::Instance()->focusModule(), &Ekos::Focus::autofocusComplete, this, [&]() {
autofocus_completed = true;
autofocus_started = false;
});
QVERIFY(completion_handler);
// Prepare to detect the failure of the autofocus procedure
volatile bool autofocus_aborted = false;
auto abort_handler = connect(Ekos::Manager::Instance()->focusModule(), &Ekos::Focus::autofocusAborted, this, [&]() {
autofocus_aborted = true;
autofocus_started = false;
});
QVERIFY(abort_handler);
// Run the autofocus, wait for the completion signal
QVERIFY(!autofocus_started);
QVERIFY(!autofocus_aborted);
QVERIFY(!autofocus_completed);
KTRY_FOCUS_CLICK(startFocusB);
QTRY_VERIFY_WITH_TIMEOUT(autofocus_started, 500);
QTRY_VERIFY_WITH_TIMEOUT(autofocus_aborted, 30000);
// No other autofocus started after that
QVERIFY(!autofocus_started);
// Disconnect signals
disconnect(startup_handler);
disconnect(completion_handler);
disconnect(abort_handler);
}
void TestEkosFocus::testStarDetection_data()
......@@ -145,39 +531,41 @@ void TestEkosFocus::testStarDetection()
QVERIFY(ekos->mountModule()->sync(RA, DEC));
// Wait for Focus to come up, switch to Focus tab
QTRY_VERIFY_WITH_TIMEOUT(ekos->focusModule() != nullptr, 5000);
KTRY_EKOS_GADGET(QTabWidget, toolsWidget);
toolsWidget->setCurrentWidget(ekos->focusModule());
QTRY_COMPARE_WITH_TIMEOUT(toolsWidget->currentWidget(), ekos->focusModule(), 1000);
KTRY_FOCUS_SHOW();
QWARN("The Focus capture button toggles after Ekos is started, leave a bit of time for it to settle.");
QTest::qWait(500);
KTRY_FOCUS_GADGET(QPushButton, startFocusB);
KTRY_FOCUS_GADGET(QPushButton, stopFocusB);
QTRY_VERIFY_WITH_TIMEOUT(startFocusB->isEnabled(), 1000);
QTRY_VERIFY_WITH_TIMEOUT(!stopFocusB->isEnabled(), 1000);
KTRY_FOCUS_GADGET(QLineEdit, starsOut);
// Locate somewhere we do see stars with the CCD Simulator
KTRY_FOCUS_MOVETO(60000);
// Run the focus procedure for SEP
KTRY_FOCUS_CONFIGURE("SEP", "Iterative", 0.0, 100.0);
KTRY_FOCUS_DETECT(1, 3);
KTRY_FOCUS_CONFIGURE("SEP", "Iterative", 0.0, 100.0, 3.0);
KTRY_FOCUS_DETECT(1, 3, 99);
QTRY_VERIFY_WITH_TIMEOUT(starsOut->text().toInt() >= 1, 5000);
// Run the focus procedure for Centroid
KTRY_FOCUS_CONFIGURE("Centroid", "Iterative", 0.0, 100.0);
KTRY_FOCUS_DETECT(1, 3);
KTRY_FOCUS_CONFIGURE("Centroid", "Iterative", 0.0, 100.0, 3.0);
KTRY_FOCUS_DETECT(1, 3, 99);
QTRY_VERIFY_WITH_TIMEOUT(starsOut->text().toInt() >= 1, 5000);
// Run the focus procedure for Threshold - disable full-field
KTRY_FOCUS_CONFIGURE("Threshold", "Iterative", 0.0, 0.0);
KTRY_FOCUS_DETECT(1, 3);
KTRY_FOCUS_CONFIGURE("Threshold", "Iterative", 0.0, 0.0, 3.0);
KTRY_FOCUS_DETECT(1, 3, 99);
QTRY_VERIFY_WITH_TIMEOUT(starsOut->text().toInt() >= 1, 5000);
// Run the focus procedure for Gradient - disable full-field
KTRY_FOCUS_CONFIGURE("Gradient", "Iterative", 0.0, 0.0);
KTRY_FOCUS_DETECT(1, 3);
KTRY_FOCUS_CONFIGURE("Gradient", "Iterative", 0.0, 0.0, 3.0);
KTRY_FOCUS_DETECT(1, 3, 99);
QTRY_VERIFY_WITH_TIMEOUT(starsOut->text().toInt() >= 1, 5000);
// Longer exposure
KTRY_FOCUS_CONFIGURE("SEP", "Iterative", 0.0, 100.0);
KTRY_FOCUS_DETECT(8, 1);
KTRY_FOCUS_CONFIGURE("SEP", "Iterative", 0.0, 100.0, 3.0);
KTRY_FOCUS_DETECT(8, 1, 99);
QTRY_VERIFY_WITH_TIMEOUT(starsOut->text().toInt() >= 1, 5000);
// Run the focus procedure again to cover more code
......@@ -187,18 +575,18 @@ void TestEkosFocus::testStarDetection()
{
for (double outer = 100.0; inner < outer; outer -= 42.0)
{
KTRY_FOCUS_CONFIGURE("SEP", "Iterative", inner, outer);
KTRY_FOCUS_DETECT(0.1, 2);
KTRY_FOCUS_CONFIGURE("SEP", "Iterative", inner, outer, 3.0);
KTRY_FOCUS_DETECT(0.1, 2, 99);
}
}
// Test threshold - disable full-field
for (double threshold = 80.0; threshold < 200.0; threshold += 13.3)
for (double threshold = 80.0; threshold < 99.0; threshold += 13.3)
{
KTRY_FOCUS_GADGET(QDoubleSpinBox, thresholdSpin);
thresholdSpin->setValue(threshold);
KTRY_FOCUS_CONFIGURE("Threshold", "Iterative", 0, 0.0);
KTRY_FOCUS_DETECT(0.1, 1);
KTRY_FOCUS_CONFIGURE("Threshold", "Iterative", 0, 0.0, 3.0);
KTRY_FOCUS_DETECT(0.1, 1, 99);
}
#endif
}
......
......@@ -23,6 +23,14 @@
#include <QCheckBox>
#include <QtTest>
/** @brief Helper to show the Focus tab
*/
#define KTRY_FOCUS_SHOW() do { \
QTRY_VERIFY_WITH_TIMEOUT(Ekos::Manager::Instance()->focusModule() != nullptr, 5000); \
KTRY_EKOS_GADGET(QTabWidget, toolsWidget); \
toolsWidget->setCurrentWidget(Ekos::Manager::Instance()->focusModule()); \
QTRY_COMPARE_WITH_TIMEOUT(toolsWidget->currentWidget(), Ekos::Manager::Instance()->focusModule(), 1000); } while (false)
/** @brief Helper to retrieve a gadget in the Focus tab specifically.
* @param klass is the class of the gadget to look for.
* @param name is the gadget name to look for in the UI configuration.
......@@ -64,9 +72,14 @@
* disabled or does not toggle during exposure or if the stop button is not the opposite of the capture button.
*/
/** @{ */
#define KTRY_FOCUS_DETECT(exposure, averaged) do { \
#define KTRY_FOCUS_EXPOSURE(exposure, gain) do { \
KTRY_FOCUS_GADGET(QDoubleSpinBox, gainIN); \
gainIN->setValue(gain); \
KTRY_FOCUS_GADGET(QDoubleSpinBox, exposureIN); \
exposureIN->setValue(exposure); \
exposureIN->setValue(exposure); } while (false)
#define KTRY_FOCUS_DETECT(exposure, averaged, gain) do { \
KTRY_FOCUS_EXPOSURE(exposure, gain); \
KTRY_FOCUS_GADGET(QSpinBox, focusFramesSpin); \
focusFramesSpin->setValue(averaged); \
KTRY_FOCUS_GADGET(QPushButton, captureB); \
......@@ -77,7 +90,7 @@
QTRY_VERIFY_WITH_TIMEOUT(!captureB->isEnabled(), 1000); \
QVERIFY(stopFocusB->isEnabled()); \
QTest::qWait(exposure*averaged*1000); \
QTRY_VERIFY_WITH_TIMEOUT(captureB->isEnabled(), 5000); \
QTRY_VERIFY_WITH_TIMEOUT(captureB->isEnabled(), 5000 + exposure*averaged*1000/5); \
QVERIFY(!stopFocusB->isEnabled()); } while (false)
/** @} */
......@@ -88,16 +101,42 @@
* @param fieldout is the upper radius of the annulus filtering stars.
* @warning Fails the test if detection, algorithm, full-field checkbox or annulus fields cannot be used.
*/
#define KTRY_FOCUS_CONFIGURE(detection, algorithm, fieldin, fieldout) do { \
#define KTRY_FOCUS_CONFIGURE(detection, algorithm, fieldin, fieldout, tolerance) do { \
KTRY_FOCUS_GADGET(QCheckBox, useFullField); \
useFullField->setCheckState(fieldin < fieldout ? Qt::CheckState::Checked : Qt::CheckState::Unchecked); \
KTRY_FOCUS_GADGET(QDoubleSpinBox, fullFieldInnerRing); \
fullFieldInnerRing->setValue(fieldin); \
KTRY_FOCUS_GADGET(QDoubleSpinBox, fullFieldOuterRing); \
fullFieldOuterRing->setValue(fieldout); \
KTRY_FOCUS_GADGET(QDoubleSpinBox, toleranceIN); \
toleranceIN->setValue(tolerance); \
KTRY_FOCUS_COMBO_SET(focusDetectionCombo, detection); \
KTRY_FOCUS_COMBO_SET(focusAlgorithmCombo, algorithm); } while (false)
/** @brief Helper to move the focuser.
* @param steps is the absolute step value to set.
*/
#define KTRY_FOCUS_MOVETO(steps) do { \
KTRY_FOCUS_GADGET(QSpinBox, absTicksSpin); \
absTicksSpin->setValue(steps); \
KTRY_FOCUS_GADGET(QPushButton, startGotoB); \
KTRY_FOCUS_CLICK(startGotoB); \
KTRY_FOCUS_GADGET(QLineEdit, absTicksLabel); \
QTRY_COMPARE_WITH_TIMEOUT(absTicksLabel->text().toInt(), steps, 5000); } while (false)
/** @brief Helper to sync the mount at the meridian for focus tests.
* @warning This is needed because the CCD Simulator has much rotation jitter at the celestial pole.
* @param alt is the altitude to sync to, use 60.0 as degrees for instance.
*/
#define KTRY_FOCUS_SYNC(alt) do { \
QWARN("Syncing mount at an altitude on the meridian to avoid celestial pole jitter on the simulator."); \
GeoLocation * const geo = KStarsData::Instance()->geo(); \
KStarsDateTime const now(KStarsData::Instance()->lt()); \
KSNumbers const numbers(now.djd()); \
CachingDms const LST = geo->GSTtoLST(geo->LTtoUT(now).gst()); \
QTRY_VERIFY_WITH_TIMEOUT(Ekos::Manager::Instance()->mountModule() != nullptr, 5000); \
QVERIFY(Ekos::Manager::Instance()->mountModule()->sync(LST.Hours(), (alt))); } while (false)
class TestEkosFocus : public QObject
{
Q_OBJECT
......@@ -112,7 +151,12 @@ private slots:
void init();
void cleanup();
void testCaptureStates();
void testDuplicateFocusRequest();
void testAutofocusSignalEmission();
void testFocusAbort();
void testGuidingSuspend();
void testFocusFailure();
void testStarDetection_data();
void testStarDetection();
......
......@@ -848,8 +848,7 @@ void Focus::start()
{
if (!changeFocus(newPosition - position))
{
abort();
setAutoFocusResult(false);
completeFocusProcedure(false);
}
// Avoid the capture below.
return;
......@@ -895,7 +894,7 @@ void Focus::checkStopFocus()