File indexing completed on 2024-04-21 14:47:21

0001 /*
0002     KStars UI tests for alignment
0003 
0004     SPDX-FileCopyrightText: 2021 Wolfgang Reissenberger <sterne-jaeger@openfuture.de>
0005 
0006     SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 
0009 #pragma once
0010 
0011 #include "config-kstars.h"
0012 #include "test_ekos.h"
0013 #include "test_ekos_capture_helper.h"
0014 
0015 #if defined(HAVE_INDI)
0016 
0017 #include <QObject>
0018 
0019 #define KTRY_CHECK_ALIGNMENTS(i) \
0020     qCInfo(KSTARS_EKOS_TEST) << "Alignment finished," << image_count << "captures," \
0021     << solver_count << "successful plate solves."; \
0022     QVERIFY(image_count == i); \
0023     QVERIFY(solver_count == i)
0024 
0025 
0026 class TestEkosAlign : public QObject
0027 {
0028     Q_OBJECT
0029 public:
0030     explicit TestEkosAlign(QObject *parent = nullptr);
0031 
0032 protected:
0033     // sequence of alignment states that are expected
0034     QQueue<Ekos::AlignState> expectedAlignStates;
0035     // sequence of telescope states that are expected
0036     QQueue<ISD::Mount::Status> expectedTelescopeStates;
0037     // sequence of capture states that are expected
0038     QQueue<Ekos::CaptureState> expectedCaptureStates;
0039 
0040     /**
0041      * @brief Track a single alignment
0042      * @param lastPoint true iff last alignment point
0043      * @param moveMount if true, an intermediate mount move is issued
0044      * @return true iff the alignment succeeded
0045      */
0046     bool trackSingleAlignment(bool lastPoint, bool moveMount);
0047 
0048 protected slots:
0049     void initTestCase();
0050     void cleanupTestCase();
0051 
0052     void init();
0053     void cleanup();
0054 
0055     void prepareTestCase();
0056 
0057     bool prepareMountModel(int points);
0058 
0059     /**
0060      * @brief Execute a mount model creation
0061      * @param points number of alignment points
0062      * @param moveMount move the mount during image capturing
0063      * @return true iff the mount model creation succeeded
0064      */
0065     bool runMountModelTool(int points, bool moveMount);
0066 
0067     /**
0068      * @brief Execute a single alignment and check if the alignment target matches the given position
0069      * @param targetObject expected target
0070      * @return true iff the alignment was successful
0071      */
0072     bool executeAlignment(SkyObject *targetObject);
0073 
0074     /**
0075      * @brief Verify if the alignment target matches the expected coordinates
0076      * @param targetObject
0077      * @return true iff the alignment target coordinates match those of the target object
0078      */
0079     bool verifyAlignmentTarget(SkyObject *targetObject);
0080 
0081     /**
0082      * @brief Helper function to test alignment with the scheduler running
0083      * @param targetObject pointer to the target object
0084      * @param fitsTarget path to a FITS image. Leave null if none should be used
0085      * @return true iff the alignment target coordinates match those of the target object
0086      */
0087     bool alignWithScheduler(SkyObject *targetObject, QString fitsTarget = nullptr);
0088 
0089     /**
0090      * @brief find a target by the name
0091      * @param name target name
0092      * @return target with JNow and J2000 coordinates set
0093      */
0094     SkyObject *findTargetByName(QString name);
0095 
0096     /**
0097      * @brief update J2000 coordinates
0098      */
0099     void updateJ2000Coordinates(SkyPoint *target);
0100 
0101 private:
0102     // helper class
0103     TestEkosCaptureHelper *m_CaptureHelper = nullptr;
0104 
0105     // test directory
0106     QTemporaryDir *testDir;
0107 
0108     // current alignment status
0109     Ekos::AlignState m_AlignStatus { Ekos::ALIGN_IDLE };
0110 
0111     // current scope status
0112     ISD::Mount::Status m_TelescopeStatus { ISD::Mount::MOUNT_IDLE };
0113 
0114     // current capture status
0115     Ekos::CaptureState m_CaptureStatus { Ekos::CAPTURE_IDLE };
0116 
0117     /**
0118      * @brief Slot to track the align status of the mount
0119      * @param status new align state
0120      */
0121     void alignStatusChanged(Ekos::AlignState status);
0122 
0123     /**
0124      * @brief Slot to track the mount status
0125      * @param status new mount state
0126      */
0127     void telescopeStatusChanged(ISD::Mount::Status status);
0128 
0129     /**
0130      * @brief Slot to track the capture status
0131      * @param status new capture status
0132      */
0133     void captureStatusChanged(Ekos::CaptureState status);
0134 
0135     /**
0136      * @brief slot to track captured images from the align process
0137      * @param view
0138      */
0139     void imageReceived(const QSharedPointer<FITSView> &view);
0140 
0141     // counter for images taken in a single test run
0142     int image_count;
0143 
0144     /**
0145      * @brief slot to track solver results from the align process
0146      * @param orientation image orientation
0147      * @param ra RA position
0148      * @param dec DEC position
0149      * @param pixscale image scale of a single image pixel
0150      */
0151     void solverResultReceived(double orientation, double ra, double dec, double pixscale);
0152 
0153     // counter of solver results in a single test run
0154     int solver_count;
0155 
0156 private slots:
0157     /**
0158      * @brief Test a simple slew and a subsequent alignment
0159      */
0160     void testSlewAlign();
0161 
0162     /**
0163      * @brief Test alignment for a sky position in an empty sky segment
0164      */
0165     void testEmptySkyAlign();
0166 
0167     /**
0168      * @brief Test if only syncs have been used the alignment uses the latest
0169      *        sync as target.
0170      */
0171     void testSyncOnlyAlign();
0172 
0173     /**
0174      * @brief Test if guide drifting leaves the alignment target untouched
0175      */
0176     void testSlewDriftAlign();
0177 
0178     /**
0179      * @brief Test aligning to target where the target definition comes from a FITS image.
0180      */
0181     void testFitsAlign();
0182 
0183     /**
0184      * @brief Test alignment to the target of a scheduled job
0185      */
0186     void testAlignTargetScheduledJob();
0187 
0188     /**
0189      * @brief Test alignment to a FITS target of a scheduled job
0190      */
0191     void testFitsAlignTargetScheduledJob();
0192 
0193     /** @brief Test if aligning gets suspended when a slew occurs and recovers when
0194      *         the scope returns to tracking mode */
0195     void testAlignRecoverFromSlewing();
0196 
0197     /** @brief Test the mount model */
0198     void testMountModel();
0199 
0200     /** @brief Test if a slew event during the mount model creation is handled correctly
0201      *         by suspending when a slew occurs and recovers when the scope returns
0202      *         to tracking mode */
0203     void testMountModelToolRecoverFromSlewing();
0204 };
0205 
0206 #endif // HAVE_INDI