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

0001 /*
0002     Tests for meridian flip state machine.
0003 
0004     SPDX-FileCopyrightText: 2022 Wolfgang Reissenberger <sterne-jaeger@openfuture.de>
0005 
0006     SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 
0009 #pragma once
0010 
0011 #include "ekos/manager/meridianflipstate.h"
0012 #include "test_ekos_helper.h"
0013 #include "indi/indimount.h"
0014 
0015 #include <QTest>
0016 #include <QObject>
0017 
0018 class MountSimulator;
0019 
0020 class TestEkosMeridianFlipState : public QObject
0021 {
0022     Q_OBJECT
0023 public:
0024     explicit TestEkosMeridianFlipState(QObject *parent = nullptr) : QObject{parent} {}
0025 
0026 protected slots:
0027     void init();
0028     /**
0029      * @brief Cleanup after the a single test case has finished.
0030      */
0031     void cleanup();
0032     /**
0033      * @brief Initialization at beginning of the run of the entire test suite.
0034      */
0035     void initTestCase();
0036     /**
0037      * @brief Cleanup after the entire test suite has finished.
0038      */
0039     void cleanupTestCase();
0040     /**
0041      * @brief Initialisation before each single test case.
0042      */
0043 
0044 private slots:
0045     /**
0046      * @brief Test case for a simple meridian flip
0047      */
0048     void testMeridianFlip();
0049 
0050     /** @brief Test data for {@see testMeridianFlip()} */
0051     void testMeridianFlip_data();
0052 
0053 private:
0054     // helper functions
0055     TestEkosHelper m_Helper;
0056     // The state machine
0057     Ekos::MeridianFlipState *m_stateMachine { nullptr };
0058     // the test adapter simulating the EKOS environment
0059     MountSimulator *m_Mount { nullptr };
0060 
0061     // current mount position
0062     Ekos::MeridianFlipState::MountPosition m_currentPosition;
0063     // current and target mount status
0064     ISD::Mount::Status m_MountStatus { ISD::Mount::MOUNT_IDLE };
0065     // sequence of mount states that are expected
0066     QQueue<ISD::Mount::Status> expectedMountStates;
0067 
0068     // current  meridian flip mount status
0069     Ekos::MeridianFlipState::MeridianFlipMountState m_MeridianFlipMountStatus { Ekos::MeridianFlipState::MOUNT_FLIP_NONE };
0070     // sequence of meridian flip mount states that are expected
0071     QQueue<Ekos::MeridianFlipState::MeridianFlipMountState> expectedMeridianFlipMountStates;
0072     // initial meridian flip delay
0073     int secs_to_mf = -1;
0074 
0075     // forward signals to the sequence job
0076     void connectAdaptor();
0077     void disconnectAdaptor();
0078 
0079     /**
0080      * @brief Determine the target close to the meridian
0081      * @param secsToMF seconds to meridian flip
0082      * @param upper set to true if close to an upper meridian flip
0083      * @return position secsToMF seconds close to the meridian
0084      */
0085     SkyPoint findMFTestTarget(int secsToMF, bool upper = true);
0086 
0087     /**
0088      * @brief Slot for receiving a new telescope position
0089      * @param position new position
0090      * @param pierSide current pier side
0091      * @param ha current hour angle
0092      */
0093     void updateTelescopeCoord(const SkyPoint &position, ISD::Mount::PierSide pierSide, const dms &ha);
0094 
0095     /**
0096      * @brief Slot to track the mount status
0097      * @param status new mount status
0098      */
0099     void mountStatusChanged(ISD::Mount::Status status);
0100 
0101     /**
0102      * @brief Slot to track the meridian flip state of the mount
0103      * @param status new meridian flip mount state
0104      */
0105     void meridianFlipMountStatusChanged(Ekos::MeridianFlipState::MeridianFlipMountState status);
0106 };
0107 
0108 /* *********************************************************************************
0109  * Test adapter
0110  * ********************************************************************************* */
0111 
0112 class MountSimulator : public QObject
0113 {
0114     Q_OBJECT
0115 
0116 public:
0117     explicit MountSimulator(){}
0118 
0119     void init(const SkyPoint &position);
0120     void shutdown();
0121     void Slew(const SkyPoint &position);
0122     void Sync(const SkyPoint &position);
0123 
0124     void setStatus(ISD::Mount::Status newStatus);
0125 
0126 signals:
0127     void newCoords(const SkyPoint &position, const ISD::Mount::PierSide pierside, const dms &ha);
0128     void newStatus(ISD::Mount::Status status);
0129 
0130 private:
0131     ISD::Mount::Status m_status {ISD::Mount::MOUNT_IDLE};
0132     // current position
0133     SkyPoint m_position;
0134     ISD::Mount::PierSide m_pierside { ISD::Mount::PIER_UNKNOWN};
0135     // target position
0136     SkyPoint m_targetPosition;
0137     ISD::Mount::PierSide m_targetPierside { ISD::Mount::PIER_UNKNOWN};
0138     // time stamps for slewing finished and for flipping pier side
0139     KStarsDateTime slewFinishedTime;
0140 
0141     void updatePosition();
0142     dms calcHA(const SkyPoint &pos);
0143     ISD::Mount::PierSide calcPierSide(const SkyPoint &pos);
0144 };