File indexing completed on 2024-04-21 14:47:26
0001 /* 0002 Base class of KStars UI tests for meridian flip 0003 0004 SPDX-FileCopyrightText: 2020 Wolfgang Reissenberger <sterne-jaeger@openfuture.de> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 0010 #include "test_ekos_meridianflip_base.h" 0011 0012 #if defined(HAVE_INDI) 0013 0014 #include <qdir.h> 0015 0016 #include "kstars_ui_tests.h" 0017 #include "test_ekos.h" 0018 0019 #include "auxiliary/dms.h" 0020 #include "ksutils.h" 0021 #include "indicom.h" 0022 #include "Options.h" 0023 #include "ekos/capture/capture.h" 0024 0025 TestEkosMeridianFlipBase::TestEkosMeridianFlipBase(QObject *parent) : 0026 TestEkosMeridianFlipBase::TestEkosMeridianFlipBase("Internal", parent) {} 0027 0028 TestEkosMeridianFlipBase::TestEkosMeridianFlipBase(QString guider, QObject *parent) : QObject(parent) 0029 { 0030 m_CaptureHelper = new TestEkosCaptureHelper(guider); 0031 m_CaptureHelper->m_FocuserDevice = "Focuser Simulator"; 0032 } 0033 0034 bool TestEkosMeridianFlipBase::startEkosProfile() 0035 { 0036 // use the helper to start the profile 0037 KWRAP_SUB(m_CaptureHelper->startEkosProfile()); 0038 // prepare optical trains for testing 0039 m_CaptureHelper->prepareOpticalTrains(); 0040 // prepare the mount module for testing (OAG guiding seems more robust) 0041 m_CaptureHelper->prepareMountModule(TestEkosHelper::SCOPE_FSQ85, TestEkosHelper::SCOPE_FSQ85); 0042 // prepare for focusing tests 0043 m_CaptureHelper->prepareFocusModule(); 0044 0045 // Everything completed successfully 0046 return true; 0047 } 0048 0049 void TestEkosMeridianFlipBase::initTestCase() 0050 { 0051 // ensure EKOS is running 0052 KVERIFY_EKOS_IS_HIDDEN(); 0053 KTRY_OPEN_EKOS(); 0054 KVERIFY_EKOS_IS_OPENED(); 0055 // Prepare PHD2 usage 0056 if (m_CaptureHelper->m_Guider == "PHD2") 0057 m_CaptureHelper->preparePHD2(); 0058 0059 // disable twilight warning 0060 KMessageBox::saveDontShowAgainYesNo("astronomical_twilight_warning", KMessageBox::ButtonCode::No); 0061 } 0062 0063 bool TestEkosMeridianFlipBase::shutdownEkosProfile() 0064 { 0065 // cleanup the capture helper 0066 m_CaptureHelper->cleanup(); 0067 // shutdown the profile 0068 return m_CaptureHelper->shutdownEkosProfile(); 0069 } 0070 0071 void TestEkosMeridianFlipBase::cleanupTestCase() 0072 { 0073 if (m_CaptureHelper->m_Guider == "PHD2") 0074 m_CaptureHelper->cleanupPHD2(); 0075 KTRY_CLOSE_EKOS(); 0076 KVERIFY_EKOS_IS_HIDDEN(); 0077 } 0078 0079 void TestEkosMeridianFlipBase::init() 0080 { 0081 // initialize the capture helper 0082 m_CaptureHelper->init(); 0083 0084 // disable by default 0085 refocus_checked = false; 0086 use_aligning = false; 0087 dithering_checked = false; 0088 0089 // reset initial focuser position 0090 initialFocusPosition = -1; 0091 0092 // set geo location 0093 KStarsData * const d = KStars::Instance()->data(); 0094 QVERIFY(d != nullptr); 0095 QFETCH(QString, location); 0096 GeoLocation * const geo = d->locationNamed(location); 0097 QVERIFY(geo != nullptr); 0098 d->setLocation(*geo); 0099 0100 // start the profile (depending on the selected guider) 0101 QVERIFY(startEkosProfile()); 0102 0103 // disable FITS viewer 0104 Options::setUseFITSViewer(false); 0105 0106 // Eliminate the noise setting to ensure a working focusing and plate solving 0107 KTRY_INDI_PROPERTY("CCD Simulator", "Simulator Config", "SIMULATOR_SETTINGS", ccd_settings); 0108 INDI_E *noise_setting = ccd_settings->getElement("SIM_NOISE"); 0109 QVERIFY(ccd_settings != nullptr); 0110 noise_setting->setValue(0.0); 0111 ccd_settings->processSetButton(); 0112 0113 // clear guiding calibration to ensure proper guiding 0114 // TestEkosHelper::prepareGuidingModule() stores a guiding calibration, override if necessary 0115 // KTRY_CLICK(Ekos::Manager::Instance()->guideModule(), clearCalibrationB); 0116 0117 // switch to mount module 0118 KTRY_SWITCH_TO_MODULE_WITH_TIMEOUT(Ekos::Manager::Instance()->mountModule(), 1000); 0119 0120 // activate meridian flip 0121 QVERIFY(enableMeridianFlip(0.0)); 0122 0123 // expected beginning of the meridian flip 0124 m_CaptureHelper->expectedMeridianFlipStates.enqueue(Ekos::MeridianFlipState::MOUNT_FLIP_PLANNED); 0125 m_CaptureHelper->expectedMeridianFlipStates.enqueue(Ekos::MeridianFlipState::MOUNT_FLIP_RUNNING); 0126 } 0127 0128 void TestEkosMeridianFlipBase::cleanup() 0129 { 0130 // ensure that capturing, focusing and guiding is stopped 0131 QVERIFY(stopScheduler()); 0132 QVERIFY(m_CaptureHelper->stopFocusing()); 0133 QVERIFY(stopAligning()); 0134 QVERIFY(stopCapturing()); 0135 QVERIFY(m_CaptureHelper->stopGuiding()); 0136 0137 // clean up capture module 0138 Ekos::Manager::Instance()->captureModule()->clearSequenceQueue(); 0139 KTRY_GADGET(Ekos::Manager::Instance()->captureModule(), QTableWidget, queueTable); 0140 QTRY_VERIFY_WITH_TIMEOUT(queueTable->rowCount() == 0, 2000); 0141 0142 // cleanup the scheduler 0143 m_CaptureHelper->cleanupScheduler(); 0144 0145 // shutdown profile and local INDI server 0146 QVERIFY(shutdownEkosProfile()); 0147 } 0148 0149 0150 0151 /* ********************************************************************************* 0152 * 0153 * Test data 0154 * 0155 * ********************************************************************************* */ 0156 0157 void TestEkosMeridianFlipBase::prepareTestData(double exptime, QList<QString> locationList, QList<bool> culminationList, 0158 QList<std::pair<QString, int> > filterList, QList<int> focusList, QList<bool> guideList, QList<bool> ditherList) 0159 { 0160 #if QT_VERSION < QT_VERSION_CHECK(5,9,0) 0161 QSKIP("Bypassing fixture test on old Qt"); 0162 Q_UNUSED(exptime) 0163 Q_UNUSED(locationList) 0164 Q_UNUSED(culminationList) 0165 Q_UNUSED(filterList) 0166 Q_UNUSED(focusList) 0167 Q_UNUSED(guideList) 0168 Q_UNUSED(ditherList) 0169 #else 0170 QTest::addColumn<QString>("location"); /*!< locations the KStars test is running for */ 0171 QTest::addColumn<bool>("culmination"); /*!< upper culmination? */ 0172 QTest::addColumn<int>("count"); /*!< frame counts to capture */ 0173 QTest::addColumn<double>("exptime"); /*!< exposure time of a single frame */ 0174 QTest::addColumn<QString>("filters"); /*!< list of filters for the capture sequence */ 0175 QTest::addColumn<int>("focus"); /*!< focusing: 0=no, 1=refocus, 2=HFR autofocus, 3=after meridian flip */ 0176 QTest::addColumn<bool>("guide"); /*!< use guiding */ 0177 QTest::addColumn<bool>("dither"); /*!< execute dithering after each capture */ 0178 0179 KStarsData * const d = KStars::Instance()->data(); 0180 QVERIFY(d != nullptr); 0181 0182 for (QString location : locationList) 0183 for (bool culmination : culminationList) 0184 for (int focus : focusList) 0185 for (bool guide : guideList) 0186 for (bool dither : ditherList) 0187 for(std::pair<QString, int> filter : filterList) 0188 { 0189 int count = filter.second; 0190 // both guide==false && dither==true does not make sense 0191 if (guide == true || dither == false) 0192 QTest::newRow(QString("%7: culm=%8, %1x%2, foc=%3, di=%4, guider=%5").arg(count).arg(filter.first) 0193 .arg(focus == 0 ? "no" : (focus == 1 ? "refocus" : (focus == 2 ? "auto" : "mf"))).arg(dither ? "yes" : "no") 0194 .arg(guide ? m_CaptureHelper->m_Guider : "none").arg(location) 0195 .arg(culmination ? "up" : "low").toLocal8Bit()) 0196 << location << culmination << count << exptime << filter.first << focus << guide << dither; 0197 } 0198 #endif 0199 } 0200 0201 /* ********************************************************************************* 0202 * 0203 * Helpers functions 0204 * 0205 * ********************************************************************************* */ 0206 0207 bool TestEkosMeridianFlipBase::positionMountForMF(int secsToMF, bool fast) 0208 { 0209 #if QT_VERSION < QT_VERSION_CHECK(5,9,0) 0210 QSKIP("Bypassing fixture test on old Qt"); 0211 Q_UNUSED(secsToMF) 0212 Q_UNUSED(fast) 0213 #else 0214 Ekos::Mount *mount = Ekos::Manager::Instance()->mountModule(); 0215 0216 findMFTestTarget(secsToMF, fast); 0217 0218 // now slew very close before the meridian 0219 mount->slew(target->ra().Hours(), target->dec().Degrees()); 0220 // wait a certain time until the mount slews 0221 QTest::qWait(3000); 0222 // wait until the mount is tracking 0223 KTRY_VERIFY_WITH_TIMEOUT_SUB(Ekos::Manager::Instance()->mountModule()->status() == ISD::Mount::MOUNT_TRACKING, 60000); 0224 // check whether a meridian flip is announced 0225 const QString flipmsg = Ekos::Manager::Instance()->mountModule()->meridianFlipStatusWidget->getStatus(); 0226 const int prefixlength = QString("Meridian flip in").length(); 0227 KWRAP_SUB(QTRY_VERIFY_WITH_TIMEOUT(flipmsg.length() >= prefixlength 0228 && flipmsg.left(prefixlength).compare("Meridian flip in") == 0, 20000)); 0229 #endif 0230 // all checks succeeded 0231 return true; 0232 } 0233 0234 bool TestEkosMeridianFlipBase::prepareMFTestcase(bool guideDeviation, bool initialGuideDeviation) 0235 { 0236 #if QT_VERSION < QT_VERSION_CHECK(5,9,0) 0237 QSKIP("Bypassing fixture test on old Qt"); 0238 Q_UNUSED(guideDeviation) 0239 Q_UNUSED(initialGuideDeviation) 0240 #else 0241 // switch to capture module 0242 KWRAP_SUB(KTRY_SWITCH_TO_MODULE_WITH_TIMEOUT(Ekos::Manager::Instance()->captureModule(), 1000)); 0243 0244 // set refocus after meridian flip 0245 QFETCH(int, focus); 0246 refocus_checked = (focus > 0); 0247 0248 // regular refocusing 0249 KTRY_SET_CHECKBOX_SUB(Ekos::Manager::Instance()->captureModule(), limitRefocusS, (focus == 1)); 0250 // HFR based refocusing 0251 KTRY_SET_CHECKBOX_SUB(Ekos::Manager::Instance()->captureModule(), limitFocusHFRS, (focus == 2)); 0252 // focus after flip 0253 KTRY_SET_CHECKBOX_SUB(Ekos::Manager::Instance()->captureModule(), meridianRefocusS, (focus == 3)); 0254 0255 // set guide deviation guard 0256 KTRY_SET_CHECKBOX_SUB(Ekos::Manager::Instance()->captureModule(), startGuiderDriftS, initialGuideDeviation); 0257 KTRY_SET_CHECKBOX_SUB(Ekos::Manager::Instance()->captureModule(), limitGuideDeviationS, guideDeviation); 0258 KTRY_SET_DOUBLESPINBOX_SUB(Ekos::Manager::Instance()->captureModule(), startGuiderDriftN, 3.0); 0259 KTRY_SET_DOUBLESPINBOX_SUB(Ekos::Manager::Instance()->captureModule(), limitGuideDeviationN, 3.0); 0260 0261 // create the capture directory 0262 QTemporaryDir destination; 0263 KWRAP_SUB(QVERIFY(destination.isValid())); 0264 KWRAP_SUB(QVERIFY(destination.autoRemove())); 0265 qCInfo(KSTARS_EKOS_TEST) << "FITS path: " << destination.path(); 0266 0267 // create capture sequence 0268 QFETCH(int, count); 0269 QFETCH(double, exptime); 0270 QFETCH(QString, filters); 0271 0272 KWRAP_SUB(foreach(QString filter, filters.split(",")) KTRY_CAPTURE_ADD_LIGHT(exptime, count, 0, filter, "test", 0273 destination.path())); 0274 0275 QFETCH(bool, guide); 0276 if (guide) 0277 { 0278 // slew roughly to the position to calibrate first 0279 KWRAP_SUB(QVERIFY(positionMountForMF(600, true))); 0280 qCInfo(KSTARS_EKOS_TEST) << "Slewed roughly to the position to calibrate first."; 0281 // calibrate guiding 0282 if (! m_CaptureHelper->startGuiding(2.0)) return false; 0283 if (! m_CaptureHelper->stopGuiding()) return false; 0284 qCInfo(KSTARS_EKOS_TEST) << "Guider calibration" << Options::serializedCalibration(); 0285 } 0286 0287 // set dithering due to test data set 0288 QFETCH(bool, dither); 0289 dithering_checked = dither; 0290 Options::setDitherEnabled(dither); 0291 0292 // all steps succeeded 0293 return true; 0294 #endif 0295 } 0296 0297 bool TestEkosMeridianFlipBase::prepareCaptureTestcase(int secsToMF, bool guideDeviation, bool initialGuideDeviation) 0298 { 0299 #if QT_VERSION < QT_VERSION_CHECK(5,9,0) 0300 QSKIP("Bypassing fixture test on old Qt"); 0301 Q_UNUSED(secsToMF) 0302 Q_UNUSED(initialFocus) 0303 Q_UNUSED(guideDeviation) 0304 Q_UNUSED(initialGuideDeviation) 0305 #else 0306 // execute preparation steps 0307 KWRAP_SUB(QVERIFY(prepareMFTestcase(guideDeviation, initialGuideDeviation))); 0308 0309 // slew close to the meridian 0310 QFETCH(bool, guide); 0311 KWRAP_SUB(QVERIFY(positionMountForMF(secsToMF, !guide))); 0312 qCInfo(KSTARS_EKOS_TEST) << "Slewed close to the meridian."; 0313 #endif 0314 // all checks succeeded 0315 return true; 0316 } 0317 0318 bool TestEkosMeridianFlipBase::prepareSchedulerTestcase(int secsToMF, bool useAlign, 0319 Ekos::CompletionCondition completionCondition, int iterations) 0320 { 0321 #if QT_VERSION < QT_VERSION_CHECK(5,9,0) 0322 QSKIP("Bypassing fixture test on old Qt"); 0323 Q_UNUSED(secsToMF) 0324 Q_UNUSED(algorithm) 0325 Q_UNUSED(completionCondition) 0326 Q_UNUSED(iterations) 0327 #else 0328 // execute all similar preparation steps for a capture test case except for target slew 0329 KVERIFY_SUB(prepareMFTestcase(false, false)); 0330 0331 // determine the target and sync close to it 0332 findMFTestTarget(secsToMF, true); 0333 0334 // save current capture sequence to Ekos sequence file 0335 QString sequenceFile = m_CaptureHelper->destination->filePath("test.esq"); 0336 qCInfo(KSTARS_EKOS_TEST) << "Sequence file" << sequenceFile << "created."; 0337 KVERIFY_SUB(Ekos::Manager::Instance()->captureModule()->saveSequenceQueue(sequenceFile)); 0338 0339 Ekos::Scheduler *scheduler = Ekos::Manager::Instance()->schedulerModule(); 0340 KWRAP_SUB(KTRY_SWITCH_TO_MODULE_WITH_TIMEOUT(scheduler, 1000)); 0341 // set sequence file 0342 scheduler->setSequence(sequenceFile); 0343 // set target 0344 KTRY_SET_LINEEDIT_SUB(scheduler, nameEdit, "test"); 0345 KTRY_SET_LINEEDIT_SUB(scheduler, raBox, target->ra0().toHMSString()); 0346 KTRY_SET_LINEEDIT_SUB(scheduler, decBox, target->dec0().toDMSString()); 0347 // define step checks 0348 QFETCH(bool, guide); 0349 // disable all step checks 0350 KTRY_SET_CHECKBOX_SUB(scheduler, schedulerTrackStep, true); 0351 KTRY_SET_CHECKBOX_SUB(scheduler, schedulerFocusStep, false); 0352 KTRY_SET_CHECKBOX_SUB(scheduler, schedulerAlignStep, useAlign); 0353 KTRY_SET_CHECKBOX_SUB(scheduler, schedulerGuideStep, guide); 0354 // ignore twilight 0355 KTRY_SET_CHECKBOX_SUB(scheduler, schedulerTwilight, false); 0356 prepareTestData(18.0, {"Greenwich"}, {true}, {{"Luminance", 6}}, {0}, {false}, {false}); 0357 // disable remember job progress 0358 Options::setRememberJobProgress(false); 0359 // disable INDI stopping after scheduler finished 0360 Options::setStopEkosAfterShutdown(false); 0361 0362 // set the completion condition 0363 switch (completionCondition) 0364 { 0365 case Ekos::FINISH_REPEAT: 0366 // repeat the job for a fixed amount 0367 KTRY_SET_RADIOBUTTON_SUB(scheduler, schedulerRepeatSequences, true); 0368 KTRY_SET_SPINBOX_SUB(scheduler, schedulerExecutionSequencesLimit, iterations); 0369 break; 0370 case Ekos::FINISH_LOOP: 0371 KTRY_SET_RADIOBUTTON_SUB(scheduler, schedulerUntilTerminated, true); 0372 break; 0373 default: 0374 QWARN(QString("Unsupported completion condition %1!").arg(completionCondition).toStdString().c_str()); 0375 return false; 0376 } 0377 // add scheduler job 0378 KTRY_CLICK_SUB(scheduler, addToQueueB); 0379 #endif 0380 // preparation successful 0381 return true; 0382 } 0383 0384 bool TestEkosMeridianFlipBase::checkDithering() 0385 { 0386 // if dithering is not selected, to nothing 0387 if (! dithering_checked) 0388 return true; 0389 0390 // reset the dithering flag 0391 m_CaptureHelper->dithered = false; 0392 0393 // wait for 120s if dithering happens 0394 KTRY_VERIFY_WITH_TIMEOUT_SUB(m_CaptureHelper->dithered == true, 120000); 0395 // all checks succeeded 0396 return true; 0397 } 0398 0399 0400 bool TestEkosMeridianFlipBase::checkRefocusing() 0401 { 0402 if (refocus_checked) 0403 { 0404 // wait until focusing has started 0405 KTRY_VERIFY_WITH_TIMEOUT_SUB(m_CaptureHelper->getFocusStatus() == Ekos::FOCUS_PROGRESS, 60000); 0406 qCInfo(KSTARS_EKOS_TEST()) << "Focus progress detected."; 0407 KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT_SUB(m_CaptureHelper->expectedFocusStates, 60000); 0408 qCInfo(KSTARS_EKOS_TEST()) << "All expected focus states received."; 0409 // check if focus completion is reached (successful or not) 0410 KTRY_VERIFY_WITH_TIMEOUT_SUB(m_CaptureHelper->getFocusStatus() == Ekos::FOCUS_COMPLETE 0411 || m_CaptureHelper->getFocusStatus() == Ekos::FOCUS_FAILED || 0412 m_CaptureHelper->getFocusStatus() == Ekos::FOCUS_ABORTED, 120000); 0413 qCInfo(KSTARS_EKOS_TEST()) << "Focusing completed."; 0414 } 0415 // focusing might have suspended guiding 0416 if (m_CaptureHelper->use_guiding) 0417 KTRY_VERIFY_WITH_TIMEOUT_SUB(m_CaptureHelper->getGuidingStatus() == Ekos::GUIDE_GUIDING, 20000); 0418 // all checks succeeded 0419 return true; 0420 } 0421 0422 bool TestEkosMeridianFlipBase::executeAlignment(double expTime) 0423 { 0424 // mark alignment 0425 use_aligning = true; 0426 // prepare for alignment tests 0427 m_CaptureHelper->prepareAlignmentModule(); 0428 0429 m_CaptureHelper->expectedAlignStates.enqueue(Ekos::ALIGN_COMPLETE); 0430 KVERIFY_SUB(m_CaptureHelper->startAligning(expTime)); 0431 KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT_SUB(m_CaptureHelper->expectedAlignStates, 60000); 0432 0433 // alignment succeeded 0434 return true; 0435 } 0436 0437 bool TestEkosMeridianFlipBase::stopAligning() 0438 { 0439 // check whether alignment is already stopped 0440 if (m_CaptureHelper->getAlignStatus() == Ekos::ALIGN_IDLE || m_CaptureHelper->getAlignStatus() == Ekos::ALIGN_ABORTED || 0441 m_CaptureHelper->getAlignStatus() == Ekos::ALIGN_FAILED || m_CaptureHelper->getAlignStatus() == Ekos::ALIGN_COMPLETE) 0442 return true; 0443 0444 // switch to alignment module 0445 KWRAP_SUB(KTRY_SWITCH_TO_MODULE_WITH_TIMEOUT(Ekos::Manager::Instance()->alignModule(), 1000)); 0446 0447 // stop alignment 0448 KTRY_GADGET_SUB(Ekos::Manager::Instance()->alignModule(), QPushButton, stopB); 0449 KTRY_CLICK_SUB(Ekos::Manager::Instance()->alignModule(), stopB); 0450 KTRY_VERIFY_WITH_TIMEOUT_SUB(m_CaptureHelper->getAlignStatus() == Ekos::ALIGN_IDLE 0451 || m_CaptureHelper->getAlignStatus() == Ekos::ALIGN_ABORTED || 0452 m_CaptureHelper->getAlignStatus() == Ekos::ALIGN_FAILED || m_CaptureHelper->getAlignStatus() == Ekos::ALIGN_COMPLETE, 5000); 0453 // all checks succeeded 0454 return true; 0455 } 0456 0457 bool TestEkosMeridianFlipBase::startCapturing() 0458 { 0459 #if QT_VERSION < QT_VERSION_CHECK(5,9,0) 0460 QSKIP("Bypassing fixture test on old Qt"); 0461 #else 0462 QFETCH(double, exptime); 0463 // Now we can estimate how many captures will happen before the meridian flip. 0464 int t2mf = std::max(secondsToMF(), 0); 0465 0466 // Ensure that dithering takes place after the flip 0467 if (dithering_checked) 0468 Options::setDitherFrames(static_cast<uint>(1 + t2mf / exptime)); 0469 0470 // switch to the capture module 0471 KWRAP_SUB(KTRY_SWITCH_TO_MODULE_WITH_TIMEOUT(Ekos::Manager::Instance()->captureModule(), 1000)); 0472 0473 // check if capture is in a stopped state 0474 Ekos::CaptureState capturestate = m_CaptureHelper->getCaptureStatus(); 0475 KWRAP_SUB(QVERIFY(capturestate == Ekos::CAPTURE_IDLE || capturestate == Ekos::CAPTURE_ABORTED || 0476 capturestate == Ekos::CAPTURE_SUSPENDED || capturestate == Ekos::CAPTURE_COMPLETE)); 0477 0478 // press start 0479 m_CaptureHelper->expectedCaptureStates.enqueue(Ekos::CAPTURE_CAPTURING); 0480 KTRY_GADGET_SUB(Ekos::Manager::Instance()->captureModule(), QPushButton, startB); 0481 KTRY_CLICK_SUB(Ekos::Manager::Instance()->captureModule(), startB); 0482 0483 // check if capturing has started 0484 KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT_SUB(m_CaptureHelper->expectedCaptureStates, 15000); 0485 #endif 0486 // all checks succeeded 0487 return true; 0488 } 0489 0490 bool TestEkosMeridianFlipBase::stopCapturing() 0491 { 0492 // check if capture is in a stopped state 0493 if (m_CaptureHelper->getCaptureStatus() == Ekos::CAPTURE_IDLE 0494 || m_CaptureHelper->getCaptureStatus() == Ekos::CAPTURE_ABORTED || 0495 m_CaptureHelper->getCaptureStatus() == Ekos::CAPTURE_COMPLETE 0496 || m_CaptureHelper->getCaptureStatus() == Ekos::CAPTURE_PAUSED || 0497 m_CaptureHelper->getCaptureStatus() == Ekos::CAPTURE_MERIDIAN_FLIP) 0498 return true; 0499 0500 // switch to the capture module 0501 KWRAP_SUB(KTRY_SWITCH_TO_MODULE_WITH_TIMEOUT(Ekos::Manager::Instance()->captureModule(), 1000)); 0502 0503 // else press stop 0504 m_CaptureHelper->expectedCaptureStates.enqueue(Ekos::CAPTURE_ABORTED); 0505 KTRY_GADGET_SUB(Ekos::Manager::Instance()->captureModule(), QPushButton, startB); 0506 KTRY_CLICK_SUB(Ekos::Manager::Instance()->captureModule(), startB); 0507 0508 // check if capturing has stopped 0509 KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT_SUB(m_CaptureHelper->expectedCaptureStates, 5000); 0510 // all checks succeeded 0511 return true; 0512 } 0513 0514 bool TestEkosMeridianFlipBase::startScheduler() 0515 { 0516 Ekos::Scheduler *scheduler = Ekos::Manager::Instance()->schedulerModule(); 0517 // set expected states 0518 // slewing detection unsure since the position is close to the target 0519 // m_CaptureHelper->expectedMountStates.append(ISD::Mount::MOUNT_SLEWING); 0520 // m_CaptureHelper->expectedMountStates.append(ISD::Mount::MOUNT_TRACKING); 0521 if (m_CaptureHelper->use_guiding == true) 0522 m_CaptureHelper->expectedGuidingStates.append(Ekos::GUIDE_GUIDING); 0523 m_CaptureHelper->expectedCaptureStates.append(Ekos::CAPTURE_CAPTURING); 0524 0525 // switch to the scheduler module and start 0526 KWRAP_SUB(KTRY_SWITCH_TO_MODULE_WITH_TIMEOUT(scheduler, 1000)); 0527 KVERIFY_SUB(m_CaptureHelper->getSchedulerStatus() == Ekos::SCHEDULER_IDLE 0528 || m_CaptureHelper->getSchedulerStatus() == Ekos::SCHEDULER_ABORTED); 0529 KTRY_CLICK_SUB(scheduler, startB); 0530 0531 // check mount slew and tracking 0532 KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT_SUB(m_CaptureHelper->expectedMountStates, 60000); 0533 // check guiding 0534 KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT_SUB(m_CaptureHelper->expectedGuidingStates, 60000); 0535 // check capturing 0536 KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT_SUB(m_CaptureHelper->expectedCaptureStates, 60000); 0537 0538 // all checks succeeded 0539 return true; 0540 } 0541 0542 bool TestEkosMeridianFlipBase::stopScheduler() 0543 { 0544 Ekos::Scheduler *scheduler = Ekos::Manager::Instance()->schedulerModule(); 0545 // switch to the capture module 0546 KWRAP_SUB(KTRY_SWITCH_TO_MODULE_WITH_TIMEOUT(scheduler, 1000)); 0547 if (m_CaptureHelper->getSchedulerStatus() == Ekos::SCHEDULER_RUNNING 0548 || m_CaptureHelper->getSchedulerStatus() == Ekos::SCHEDULER_PAUSED) 0549 KTRY_CLICK_SUB(scheduler, startB); 0550 // all checks succeeded 0551 return true; 0552 } 0553 0554 bool TestEkosMeridianFlipBase::enableMeridianFlip(double delay) 0555 { 0556 Ekos::Manager * const ekos = Ekos::Manager::Instance(); 0557 KTRY_SET_CHECKBOX_SUB(ekos->mountModule(), executeMeridianFlip, true); 0558 // set the delay in degrees 0559 KTRY_SET_DOUBLESPINBOX_SUB(ekos->mountModule(), meridianFlipOffsetDegrees, 15.0 * delay / 3600.0); 0560 // all checks succeeded 0561 return true; 0562 } 0563 0564 0565 bool TestEkosMeridianFlipBase::checkMFStarted(int startDelay) 0566 { 0567 // check if the meridian flip starts running 0568 KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT_SUB(m_CaptureHelper->expectedMeridianFlipStates, startDelay * 1000); 0569 // all checks succeeded 0570 return true; 0571 } 0572 0573 bool TestEkosMeridianFlipBase::checkMFExecuted(int startDelay) 0574 { 0575 // check if the meridian flip starts running 0576 KVERIFY_SUB(checkMFStarted(startDelay)); 0577 // if dithering test required, set the dithering frequency to 1 0578 if (dithering_checked) 0579 Options::setDitherFrames(1); 0580 // check if the meridian flip is completed latest after one minute 0581 m_CaptureHelper->expectedMeridianFlipStates.enqueue(Ekos::MeridianFlipState::MOUNT_FLIP_COMPLETED); 0582 KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT_SUB(m_CaptureHelper->expectedMeridianFlipStates, 60000); 0583 // all checks succeeded 0584 return true; 0585 } 0586 0587 bool TestEkosMeridianFlipBase::checkPostMFBehavior() 0588 { 0589 // check if alignment succeeded 0590 if (use_aligning) 0591 { 0592 m_CaptureHelper->expectedAlignStates.enqueue(Ekos::ALIGN_COMPLETE); 0593 KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT_SUB(m_CaptureHelper->expectedAlignStates, 120000); 0594 } 0595 0596 // check if guiding is running 0597 if (m_CaptureHelper->use_guiding) 0598 KTRY_VERIFY_WITH_TIMEOUT_SUB(m_CaptureHelper->getGuidingStatus() == Ekos::GUIDE_GUIDING, 30000); 0599 0600 // check refocusing, that should happen immediately after the guiding calibration 0601 KWRAP_SUB(QVERIFY(checkRefocusing())); 0602 0603 // check if capturing has been started 0604 // dithering happen after first capture 0605 // otherwise it is sufficient to wait for start of capturing 0606 if (dithering_checked) 0607 { 0608 m_CaptureHelper->expectedCaptureStates.enqueue(Ekos::CAPTURE_IMAGE_RECEIVED); 0609 KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT_SUB(m_CaptureHelper->expectedCaptureStates, 60000); 0610 } 0611 else 0612 KTRY_VERIFY_WITH_TIMEOUT_SUB(m_CaptureHelper->getCaptureStatus() == Ekos::CAPTURE_CAPTURING, 60000); 0613 0614 // After the first capture dithering should take place 0615 KWRAP_SUB(QVERIFY(checkDithering())); 0616 0617 qCInfo(KSTARS_EKOS_TEST()) << "Post meridian flip steps completed."; 0618 return true; 0619 } 0620 0621 int TestEkosMeridianFlipBase::secondsToMF() 0622 { 0623 const QString flipmsg = Ekos::Manager::Instance()->mountModule()->meridianFlipStatusWidget->getStatus(); 0624 0625 return m_CaptureHelper->secondsToMF(flipmsg); 0626 } 0627 0628 void TestEkosMeridianFlipBase::findMFTestTarget(int secsToMF, bool fast) 0629 { 0630 Ekos::Mount *mount = Ekos::Manager::Instance()->mountModule(); 0631 0632 // translate seconds into fractions of hours 0633 double delta = static_cast<double>(secsToMF) / 3600.0; 0634 0635 dms lst = KStarsData::Instance()->geo()->GSTtoLST(KStarsData::Instance()->clock()->utc().gst()); 0636 0637 // upper or lower culmination? 0638 QFETCH(bool, culmination); 0639 double meridianRA = lst.Hours() + (culmination ? 0.0 : 12.0); 0640 0641 // calculate a feasible declination depending to the location's latitude 0642 // for the upper culmination, we use an azimuth of 45 deg, for the lower culmination half way between pole and horizont 0643 double lat = KStarsData::Instance()->geo()->lat()->Degrees(); 0644 target = new SkyPoint(range24(meridianRA + delta), culmination ? (lat - 45) : (90 - lat / 2)); 0645 m_CaptureHelper->updateJ2000Coordinates(target); 0646 if (fast) 0647 { 0648 // reset mount model 0649 mount->resetModel(); 0650 // sync to a point close before the meridian to speed up slewing 0651 mount->sync(range24(target->ra().Hours() + 0.002), target->dec().Degrees()); 0652 } 0653 } 0654 0655 0656 #endif // HAVE_INDI