Commit 652039e0 authored by Wolfgang Reissenberger's avatar Wolfgang Reissenberger Committed by Jasem Mutlaq

Bugfix correcting meridian flip states for double meridian flips

This change partly removes changes introduced with https://phabricator.kde.org/D29355
that cause problems when the mount attempts to execute a second meridian flip.

Capture should only use the states FLIP_WAITING and FLIP_ACCEPTED for communication
with Mount about meridian flip handling. Therefore Mount should not derive from
the meridian flip states that Capture sends, in which state exactly the Capture
module is and should not store the Capture meridian flip state.
parent 5d7ff49e
......@@ -15,6 +15,8 @@ ECM_ADD_APP_ICON(KSTARS_UI_TESTS_SRC ICONS
QT5_ADD_RESOURCES(KSTARS_UI_TESTS_SRC ../../kstars/data/kstars.qrc)
ecm_qt_declare_logging_category(KSTARS_UI_TESTS_SRC HEADER test_ekos_debug.h IDENTIFIER KSTARS_EKOS_TEST CATEGORY_NAME org.kde.kstars.ekos.test)
IF (INDI_FOUND)
INCLUDE_DIRECTORIES(${INDI_INCLUDE_DIR})
......@@ -40,6 +42,20 @@ ADD_EXECUTABLE(test_ekos_capture ${KSTARS_UI_EKOS_SRC} test_ekos_capture.cpp)
TARGET_LINK_LIBRARIES(test_ekos_capture ${KSTARS_UI_EKOS_LIBS})
ADD_TEST(NAME TestEkosCapture COMMAND test_ekos_capture)
ADD_EXECUTABLE(test_ekos_meridianflip ${KSTARS_UI_EKOS_SRC} test_ekos_meridianflip_base.cpp test_ekos_meridianflip.cpp)
TARGET_LINK_LIBRARIES(test_ekos_meridianflip ${KSTARS_UI_EKOS_LIBS})
# excluded to avoid CI timelimit failure
# ADD_TEST(NAME TestEkosMeridianFlip COMMAND test_ekos_meridianflip)
ADD_CUSTOM_COMMAND( TARGET test_ekos_meridianflip POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/phd2_Simulators_mf.PHDGuidingV2
${CMAKE_CURRENT_BINARY_DIR}/.PHDGuidingV2_mf)
ADD_EXECUTABLE(test_ekos_meridianflip_specials ${KSTARS_UI_EKOS_SRC} test_ekos_meridianflip_base.cpp test_ekos_meridianflip_specials.cpp)
TARGET_LINK_LIBRARIES(test_ekos_meridianflip_specials ${KSTARS_UI_EKOS_LIBS})
# excluded to avoid CI timelimit failure
# ADD_TEST(NAME TestEkosMeridianFlipSpecials COMMAND test_ekos_meridianflip_specials)
ADD_EXECUTABLE(test_ekos_guide ${KSTARS_UI_EKOS_SRC} test_ekos_guide.cpp)
TARGET_LINK_LIBRARIES(test_ekos_guide ${KSTARS_UI_EKOS_LIBS})
ADD_CUSTOM_COMMAND( TARGET test_ekos_guide POST_BUILD
......
ConfigVersion=2001
LoggingMode=1
currentProfile=2
ServerMode=1
perspective=layout2|name=MainToolBar;caption=Main tool bar;state=2106108;dir=3;layer=10;row=0;pos=0;prop=100000;bestw=575;besth=42;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=Guider;caption=Guider;state=256;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=640;besth=512;minw=640;minh=512;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=GraphLog;caption=Verlauf der Nachführung;state=2099196;dir=3;layer=0;row=0;pos=0;prop=151286;bestw=542;besth=247;minw=-1;minh=240;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=Stats;caption=Nachführstatistik;state=2099198;dir=4;layer=0;row=0;pos=0;prop=100000;bestw=250;besth=428;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=AOPosition;caption=AO Position;state=2099198;dir=4;layer=0;row=0;pos=0;prop=100000;bestw=293;besth=207;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=Profile;caption=Sternprofil;state=2099198;dir=3;layer=0;row=0;pos=1;prop=48714;bestw=20;besth=20;minw=115;minh=85;maxw=-1;maxh=-1;floatx=1244;floaty=492;floatw=400;floath=250|name=Target;caption=Trefferverteilung;state=2099196;dir=2;layer=0;row=0;pos=0;prop=100000;bestw=333;besth=207;minw=293;minh=208;maxw=-1;maxh=-1;floatx=1280;floaty=402;floatw=400;floath=250|dock_size(3,10,0)=44|dock_size(5,0,0)=642|dock_size(3,0,0)=278|dock_size(2,0,0)=295|
geometry=0;1175;600;441;206
profileFilePath=/home/tallfurryman/Documents/kstars/Tests/kstars_ui
wxLanguage=89
[profile]
[profile/2]
name=phd2_Simulators
AutoLoadCalibration=1
NoiseReductionMethod=0
DitherScaleFactor=1
DitherRaOnly=0
DitherMode=0
ExposureDurationMs=2000
BeepForLostStar=0
[profile/2/scope]
CalibrationDuration=155
CalibrationDistance=12
MaxRaDuration=2500
MaxDecDuration=2500
DecGuideMode=1
XGuideAlgorithm=1
YGuideAlgorithm=4
CalFlipRequiresDecFlip=0
AssumeOrthogonal=0
UseDecComp=1
StopGuidingWhenSlewing=1
LastMenuChoice=INDI Mount [Telescope Simulator]
LastAuxMenuChoice=
HiResEncoders=0
BacklashCompEnabled=0
DecBacklashPulse=20
DecBacklashFloor=20
DecBacklashCeiling=20
[profile/2/scope/GuideAlgorithm]
[profile/2/scope/GuideAlgorithm/X]
[profile/2/scope/GuideAlgorithm/X/Hysteresis]
minMove=0.28
hysteresis=0.1
aggression=0.7
[profile/2/scope/GuideAlgorithm/Y]
[profile/2/scope/GuideAlgorithm/Y/ResistSwitch]
minMove=0.28
aggression=1
fastSwitch=1
[profile/2/scope/calibration]
timestamp=Di 22 Sep 2020 18:22:48 CEST
xAngle=-1.57066
yAngle=3.14156
xRate=0.00683614
yRate=0.00707345
binning=1
declination=0.191986
pierSide=1
raGuideParity=1
decGuideParity=-1
rotatorAngle=-888
focal_length=400
image_scale=2.68144
ra_guide_rate=0.00207771
dec_guide_rate=0.00207771
ortho_error=0.00941735
orig_binning=1
orig_timestamp=Di 22 Sep 2020 15:23:20 CEST
orig_pierside=1
ra_steps={0.0 0.0}, {0.0 -5.0}, {0.0 -10.0}, {0.0 -15.0}, {0.0 -20.0}, {0.0 -24.0}, {0.0 -29.0}, {0.0 -29.0}, {0.0 -14.0}, {0.0 -0.0}
dec_steps={0.0 0.0}, {5.0 -0.0}, {10.0 -0.0}, {15.0 0.0}, {20.0 -0.0}, {25.0 -0.0}, {30.0 -0.0}, {30.0 -0.0}, {18.0 -0.0}, {6.0 -0.0}, {-0.0 -0.0}
ra_step_count=6
dec_step_count=6
last_issue=0
[profile/2/camera]
LastMenuchoice=INDI Camera [Guide Simulator]
pixelsize=5.2
binning=1
AutoLoadDefectMap=1
AutoLoadDarks=1
UseSubframes=0
TimeoutMs=15000
SaturationByADU=1
SaturationADU=65535
[profile/2/stepguider]
LastMenuChoice=
[profile/2/frame]
focalLength=900
timeLapse=0
[profile/2/CalStepCalc]
GuideSpeed=0.5
CalDeclination=60
NumSteps=6
[profile/2/rotator]
LastMenuChoice=
[profile/2/auto_exp]
exposure_min=1000
exposure_max=5000
target_snr=6
[profile/2/guider]
FastRecenter=1
ScaleImage=1
StarMinHFD=0
AutoSelDownsample=0
[profile/2/guider/onestar]
MassChangeThreshold=0.5
MassChangeThresholdEnabled=1
TolerateJumpsEnabled=0
TolerateJumpsThreshold=4
SearchRegion=15
[profile/2/overlay]
[profile/2/overlay/slit]
center.x=376
center.y=290
width=8
height=100
angle=0
[profile/2/indi]
INDIhost=localhost
INDIport=7624
INDIcam=Guide Simulator
INDIcam_ccd=0
INDIcam_forcevideo=0
INDIcam_forceexposure=0
INDIcam_port=
INDImount=Telescope Simulator
INDImount_port=
[profile/2/ImageLogger]
LoggingEnabled=0
LogFramesOverThreshRel=0
LogFramesOverThreshPx=0
LogFramesDropped=0
LogAutoSelectFrames=0
ErrorThreshRel=4
ErrorThreshPx=4
[graph]
RAColor=#6464FF
DecColor=#FF0000
minLength=50
maxLength=400
minHeight=1
maxHeight=16
[Update]
enabled=0
series=0
[Confirm]
[Confirm/2]
DarksWarningEnabled=0
......@@ -54,7 +54,7 @@
#define KTRY_PROFILEEDITOR_GADGET(klass, name) klass * name = nullptr; \
do { \
ProfileEditor* profileEditor = ekos->findChild<ProfileEditor*>("profileEditorDialog"); \
ProfileEditor* profileEditor = Ekos::Manager::Instance()->findChild<ProfileEditor*>("profileEditorDialog"); \
QVERIFY2(profileEditor != nullptr && profileEditor->isVisible(), "Profile Editor is not visible."); \
name = Ekos::Manager::Instance()->findChild<klass*>(#name); \
QVERIFY2(name != nullptr, QString(#klass "'%1' does not exist and cannot be used").arg(#name).toStdString().c_str()); \
......
......@@ -72,11 +72,11 @@
captureCountN->setValue((int)(count)); \
KTRY_CAPTURE_GADGET(QSpinBox, captureDelayN); \
captureDelayN->setValue((int)(delay)); \
KTRY_CAPTURE_GADGET(QComboBox, captureFilterS); \
KTRY_CAPTURE_GADGET(QComboBox, captureTypeS); \
KTRY_CAPTURE_COMBO_SET(captureTypeS, "Light"); \
KTRY_CAPTURE_GADGET(QComboBox, captureFormatS); \
KTRY_CAPTURE_COMBO_SET(captureFormatS, "FITS"); \
KTRY_CAPTURE_GADGET(QComboBox, captureTypeS); \
KTRY_CAPTURE_GADGET(QComboBox, captureFilterS); \
KTRY_CAPTURE_COMBO_SET(captureFilterS, (filter)); \
KTRY_CAPTURE_GADGET(QLineEdit, fileDirectoryT); \
fileDirectoryT->setText(destination); \
......
/*
KStars UI tests for meridian flip
Copyright (C) 2020
Wolfgang Reissenberger <sterne-jaeger@openfuture.de>
This application is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
*/
#include "test_ekos_meridianflip.h"
#if defined(HAVE_INDI)
#include <qdir.h>
#include "kstars_ui_tests.h"
#include "test_ekos.h"
#include "test_ekos_simulator.h"
#include "auxiliary/dms.h"
#include "ksutils.h"
#include "ekos/guide/internalguide/gmath.h"
#include "Options.h"
/* *****************************************************************************
*
* Properly executing a meridian flip and continuing afterwards in exactly the
* same way as before is a challenge:
* - If no capturing is running, it should simply take place.
* - If capturing is running, the meridian flip should wait until the current
* frame is captured, capturing is suspended, the meridian flip takes place
* and capturing continues where it was suspended. This needs to be tested if
* a meridian flip happens in the middle of a capture sequence or between two
* of them. Therefore, all capture tests are executed for a LLL sequence and
* a RGB sequence. In addition:
* - if guiding was active, guiding should be activated again after the meridian
* flip and afterwards guiding should continue
* - if an alignment has taken place after the last slew, a re-alignment should
* be executed after the flip and before guiding and capturing.
* All this could be combined with the pre-capturing actions of focusing and
* dithering.
*
* The tests are available both for the internal guider and for PHD2. For testing
* with PHD2, invoke the test with the arguments -guider PHD2.
* ***************************************************************************** */
TestEkosMeridianFlip::TestEkosMeridianFlip(QObject *parent) : TestEkosMeridianFlipBase(parent)
{
}
TestEkosMeridianFlip::TestEkosMeridianFlip(QString guider, QObject *parent) : TestEkosMeridianFlipBase(guider, parent)
{
}
void TestEkosMeridianFlip::testSimpleMF()
{
// slew close to the meridian
QVERIFY(positionMountForMF(7.0));
// check if meridian flip runs and completes successfully
QVERIFY(checkMFExecuted(10));
}
void TestEkosMeridianFlip::testSimpleMFDelay()
{
// switch to mount module
KTRY_SWITCH_TO_MODULE_WITH_TIMEOUT(Ekos::Manager::Instance()->mountModule(), 1000);
double delay = 12.0;
// activate meridian flip
QVERIFY(enableMeridianFlip(delay));
// slew close to the meridian
QVERIFY(positionMountForMF(7.0));
// check that the meridian flip is distance is in the expected corridor
int distance = secondsToMF();
QTRY_VERIFY(delay < distance && distance < delay + 7);
// check if meridian flip runs and completes successfully
QVERIFY(checkMFExecuted(static_cast<int>(delay) + 7));
}
void TestEkosMeridianFlip::testGuidingMF()
{
// slew close to the meridian
QVERIFY(positionMountForMF(75.0));
// start guiding
QVERIFY(startGuiding(2.0));
// expected guiding behavior during the meridian flip
expectedGuidingStates.enqueue(Ekos::GUIDE_ABORTED);
// check if meridian flip runs and completes successfully
QVERIFY(checkMFExecuted(80));
// meridian flip should have been aborted
KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT(expectedGuidingStates, 0.0);
// check if guiding has NOT been restarted (since we are not capturing
QTRY_VERIFY_WITH_TIMEOUT(getGuidingStatus() == Ekos::GUIDE_IDLE || getGuidingStatus() == Ekos::GUIDE_ABORTED, 10000);
}
void TestEkosMeridianFlip::testCaptureMF()
{
// set up the capture sequence
QVERIFY(prepareCaptureTestcase(10, false, true));
// start capturing
QVERIFY(startCapturing());
// check if single capture completes correctly
expectedCaptureStates.enqueue(Ekos::CAPTURE_IMAGE_RECEIVED);
// expect one additional captures to ensure refocusing after the flip
if (refocus_checked)
expectedCaptureStates.enqueue(Ekos::CAPTURE_IMAGE_RECEIVED);
KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT(expectedCaptureStates, refocus_checked?61000:21000);
// check if meridian flip runs and completes successfully
QVERIFY(checkMFExecuted(15));
// expect at least one capture
expectedCaptureStates.enqueue(Ekos::CAPTURE_CAPTURING);
// check refocusing
QVERIFY(checkRefocusing(false));
// check if capturing continues
KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT(expectedCaptureStates, 5000);
}
void TestEkosMeridianFlip::testCaptureMFAbortWaiting()
{
// set up the capture sequence
QVERIFY(prepareCaptureTestcase(10, false, false));
// start capturing
QVERIFY(startCapturing());
// Let capture run a little bit
QTest::qWait(5000);
// stop capturing
expectedCaptureStates.enqueue(Ekos::CAPTURE_ABORTED);
KTRY_CLICK(Ekos::Manager::Instance()->captureModule(), startB);
KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT(expectedCaptureStates, 2000);
// check if meridian flip runs and completes successfully
QVERIFY(checkMFExecuted(18));
// wait for settling
QTest::qWait(2000);
// check if capturing remains aborted
QVERIFY(getCaptureStatus() == Ekos::CAPTURE_IDLE);
}
void TestEkosMeridianFlip::testCaptureMFAbortFlipping()
{
// set up the capture sequence
QVERIFY(prepareCaptureTestcase(10, false, false));
// start capturing
QVERIFY(startCapturing());
// check if the meridian flip starts running
KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT(expectedMeridianFlipStates, 22000);
// Let capture run a little bit
QTest::qWait(2000);
// stop capturing
expectedCaptureStates.enqueue(Ekos::CAPTURE_ABORTED);
KTRY_CLICK(Ekos::Manager::Instance()->captureModule(), startB);
KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT(expectedCaptureStates, 2000);
// check if the meridian flip is completed latest after one minute
expectedMeridianFlipStates.enqueue(Ekos::Mount::FLIP_COMPLETED);
KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT(expectedMeridianFlipStates, 60000);
// wait for settling
QTest::qWait(2000);
// check if capturing remains aborted
QVERIFY(getCaptureStatus() == Ekos::CAPTURE_IDLE);
}
void TestEkosMeridianFlip::testCaptureGuidingMF()
{
// set up the capture sequence
QVERIFY(prepareCaptureTestcase(15, true, true));
// start guiding
QVERIFY(startGuiding(2.0));
// start capturing
QVERIFY(startCapturing());
// check if single capture completes correctly
expectedCaptureStates.enqueue(Ekos::CAPTURE_IMAGE_RECEIVED);
KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT(expectedCaptureStates, 21000);
// check if meridian flip runs and completes successfully
QVERIFY(checkMFExecuted(25));
// expected behavior after the meridian flip
expectedCaptureStates.enqueue(Ekos::CAPTURE_CAPTURING);
// check if guiding continues (re-calibration necessary)
QTRY_VERIFY_WITH_TIMEOUT(getGuidingStatus() == Ekos::GUIDE_GUIDING, 75000);
// check refocusing, that should happen immediately after the guiding calibration
QVERIFY(checkRefocusing(true));
// check if capturing continues
QTRY_VERIFY_WITH_TIMEOUT(getCaptureStatus() == Ekos::CAPTURE_CAPTURING, 20000);
// After the first capture dithering should take place
QVERIFY(checkDithering());
}
void TestEkosMeridianFlip::testCaptureAlignMF()
{
// set up the capture sequence
QVERIFY(prepareCaptureTestcase(45, false, true));
// start alignment
QVERIFY(startAligning(5.0));
// start capturing
QVERIFY(startCapturing());
// check if single capture completes correctly
expectedCaptureStates.enqueue(Ekos::CAPTURE_IMAGE_RECEIVED);
KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT(expectedCaptureStates, 21000);
// check if meridian flip runs and completes successfully
QVERIFY(checkMFExecuted(25));
// expected behavior after the meridian flip
expectedCaptureStates.enqueue(Ekos::CAPTURE_CAPTURING);
// check if alignment takes place
QTRY_VERIFY_WITH_TIMEOUT(getAlignStatus() == Ekos::ALIGN_COMPLETE, 60000);
// check refocusing
QVERIFY(checkRefocusing(false));
// check if capturing continues
QTRY_VERIFY_WITH_TIMEOUT(getCaptureStatus() == Ekos::CAPTURE_CAPTURING, 20000);
}
void TestEkosMeridianFlip::testCaptureAlignGuidingMF()
{
// set up the capture sequence
QVERIFY(prepareCaptureTestcase(40, true, true));
// start alignment
QVERIFY(startAligning(5.0));
// start guiding
QVERIFY(startGuiding(2.0));
// start capturing
QVERIFY(startCapturing());
// check if single capture completes correctly
expectedCaptureStates.enqueue(Ekos::CAPTURE_IMAGE_RECEIVED);
KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT(expectedCaptureStates, 21000);
// check if meridian flip runs and completes successfully
QVERIFY(checkMFExecuted(25));
// expected behavior after the meridian flip
expectedCaptureStates.enqueue(Ekos::CAPTURE_CAPTURING);
expectedGuidingStates.enqueue(Ekos::GUIDE_GUIDING);
// check if alignment takes place
expectedAlignStates.enqueue(Ekos::ALIGN_COMPLETE);
KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT(expectedAlignStates, 60000);
// check if guiding continues (re-calibration necessary)
KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT(expectedGuidingStates, 75000);
// check refocusing, that should happen immediately after the guiding calibration
QVERIFY(checkRefocusing(true));
// check if capturing continues
QTRY_VERIFY_WITH_TIMEOUT(getCaptureStatus() == Ekos::CAPTURE_CAPTURING, 25000);
// After the first capture dithering should take place
QVERIFY(checkDithering());
}
/* *********************************************************************************
*
* Test data
*
* ********************************************************************************* */
void TestEkosMeridianFlip::testSimpleMF_data()
{
prepareTestData({"Luminance"}, {false}, {false}, {false});
}
void TestEkosMeridianFlip::testSimpleMFDelay_data()
{
testSimpleMF_data();
}
void TestEkosMeridianFlip::testGuidingMF_data()
{
prepareTestData({"Luminance"}, {false}, {false}, {false});
}
void TestEkosMeridianFlip::testCaptureMF_data()
{
prepareTestData({"Luminance", "Red,Green,Blue,Red,Green,Blue"}, {false, true}, {false, true}, {false});
}
void TestEkosMeridianFlip::testCaptureMFAbortWaiting_data()
{
// no tests for focusing and dithering
prepareTestData({"Luminance", "Red,Green,Blue,Red,Green,Blue"}, {false}, {false}, {false});
}
void TestEkosMeridianFlip::testCaptureMFAbortFlipping_data()
{
testCaptureMFAbortWaiting_data();
}
void TestEkosMeridianFlip::testCaptureGuidingMF_data()
{
prepareTestData({"Luminance", "Red,Green,Blue,Red,Green,Blue"}, {false, true}, {false, true}, {false, true});
}
void TestEkosMeridianFlip::testCaptureAlignMF_data()
{
testCaptureMF_data();
}
void TestEkosMeridianFlip::testCaptureAlignGuidingMF_data()
{
testCaptureGuidingMF_data();
}
QTEST_KSTARS_MAIN_GUIDERSELECT(TestEkosMeridianFlip)
#endif // HAVE_INDI
/*
KStars UI tests for meridian flip
Copyright (C) 2020
Wolfgang Reissenberger <sterne-jaeger@openfuture.de>
This application is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
*/
#pragma once
#include "config-kstars.h"
#include "test_ekos_meridianflip_base.h"
#if defined(HAVE_INDI)
class TestEkosMeridianFlip : public TestEkosMeridianFlipBase
{
Q_OBJECT
public:
explicit TestEkosMeridianFlip(QObject *parent = nullptr);
explicit TestEkosMeridianFlip(QString guider, QObject *parent = nullptr);
private slots:
/** @brief Test a meridian flip without running capture sequence. */
void testSimpleMF();
/** @brief Test data for @see testSimpleMF() */
void testSimpleMF_data();
/** @brief Test the delay of a meridian flip without running a capture sequence */
void testSimpleMFDelay();
/** @brief Test data for @see testSimpleMFDelay() */
void testSimpleMFDelay_data();
/**
* @brief Test a meridian flip with guiding running
*/
void testGuidingMF();
/** @brief Test data for @see testGuidingMF() */
void testGuidingMF_data();
/** @brief Test a meridian flip during a simple capture sequence */
void testCaptureMF();
/** @brief Test data for @see testCaptureMF() */
void testCaptureMF_data();
/** @brief Test a meridian flip during a simple capture sequence, where the capture is aborted during the waiting state */
void testCaptureMFAbortWaiting();
/** @brief Test data for @see testCaptureMFAbortWaiting() */
void testCaptureMFAbortWaiting_data();
/** @brief Test a meridian flip during a simple capture sequence, where the capture is aborted during the flip */
void testCaptureMFAbortFlipping();
/** @brief Test data for @see testCaptureMFAbortWaiting() */
void testCaptureMFAbortFlipping_data();
/** @brief Test a meridian flip during a simple capture sequence with guiding on */
void testCaptureGuidingMF();
/** @brief Test data for @see testCaptureMF() */
void testCaptureGuidingMF_data();