File indexing completed on 2024-04-21 03:44:09
0001 /* 0002 SPDX-FileCopyrightText: 2012 Jasem Mutlaq <mutlaqja@ikarustech.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include <QDBusArgument> 0010 #include <QTimer> 0011 0012 #include "indiconcretedevice.h" 0013 #include "skypoint.h" 0014 0015 class SkyObject; 0016 0017 namespace ISD 0018 { 0019 /** 0020 * @class Mount 0021 * device handle controlling Mounts. It can slew and sync to a specific sky point and supports all standard properties with INDI 0022 * telescope device. 0023 * 0024 * @author Jasem Mutlaq 0025 */ 0026 class Mount : public ConcreteDevice 0027 { 0028 Q_OBJECT 0029 0030 public: 0031 explicit Mount(GenericDevice *parent); 0032 virtual ~Mount() override = default; 0033 0034 typedef enum { MOTION_NORTH, MOTION_SOUTH } VerticalMotion; 0035 typedef enum { MOTION_WEST, MOTION_EAST } HorizontalMotion; 0036 typedef enum { MOTION_START, MOTION_STOP } MotionCommand; 0037 typedef enum { PIER_UNKNOWN = -1, PIER_WEST = 0, PIER_EAST = 1 } PierSide; 0038 static QString pierSideStateString(PierSide ps) 0039 { 0040 switch (ps) 0041 { 0042 case ISD::Mount::PierSide::PIER_EAST: 0043 return "Pier Side: East (pointing West)"; 0044 case ISD::Mount::PierSide::PIER_WEST: 0045 return "Pier Side: West (pointing East)"; 0046 default: 0047 return "Pier Side: Unknown"; 0048 } 0049 } 0050 0051 typedef enum 0052 { 0053 MOUNT_IDLE, 0054 MOUNT_MOVING, 0055 MOUNT_SLEWING, 0056 MOUNT_TRACKING, 0057 MOUNT_PARKING, 0058 MOUNT_PARKED, 0059 MOUNT_ERROR 0060 } Status; 0061 typedef enum { PARK_OPTION_CURRENT, PARK_OPTION_DEFAULT, PARK_OPTION_WRITE_DATA } ParkOptionCommand; 0062 typedef enum { TRACK_SIDEREAL, TRACK_SOLAR, TRACK_LUNAR, TRACK_CUSTOM } TrackModes; 0063 0064 0065 static const QList<const char *> mountStates; 0066 0067 void registerProperty(INDI::Property prop) override; 0068 void processSwitch(INDI::Property prop) override; 0069 void processText(INDI::Property prop) override; 0070 void processNumber(INDI::Property prop) override; 0071 0072 // Coordinates 0073 bool getEqCoords(double *ra, double *dec); 0074 bool isJ2000() 0075 { 0076 return m_isJ2000; 0077 } 0078 0079 // Slew 0080 bool Slew(SkyPoint *ScopeTarget, bool flip=false); 0081 bool Slew(double ra, double dec, bool flip=false); 0082 bool canGoto() 0083 { 0084 return m_canGoto; 0085 } 0086 bool canFlip() 0087 { 0088 return m_canFlip; 0089 } 0090 0091 // Sync 0092 bool Sync(SkyPoint *ScopeTarget); 0093 bool Sync(double ra, double dec); 0094 bool canSync() 0095 { 0096 return m_canSync; 0097 } 0098 0099 // Tracking 0100 bool canControlTrack() const 0101 { 0102 return m_canControlTrack; 0103 } 0104 bool isTracking(); 0105 0106 // Track Mode 0107 bool hasTrackModes() const 0108 { 0109 return m_hasTrackModes; 0110 } 0111 bool getTrackMode(uint8_t &index); 0112 0113 // Custom Track Rate 0114 bool hasCustomTrackRate() const 0115 { 0116 return m_hasTrackModes; 0117 } 0118 bool getCustomTrackRate(double &raRate, double &deRate); 0119 0120 // Motion 0121 bool MoveNS(VerticalMotion dir, MotionCommand cmd); 0122 bool StopNS(); 0123 bool MoveWE(HorizontalMotion dir, MotionCommand cmd); 0124 bool StopWE(); 0125 bool isReversed(INDI_EQ_AXIS axis); 0126 bool setReversedEnabled(INDI_EQ_AXIS axis, bool enabled); 0127 bool isSlewing(); 0128 bool isInMotion(); 0129 bool canAbort() 0130 { 0131 return m_canAbort; 0132 } 0133 QString getManualMotionString() const; 0134 0135 // Guiding 0136 bool canGuide(); 0137 bool doPulse(GuideDirection ra_dir, int ra_msecs, GuideDirection dec_dir, int dec_msecs); 0138 bool doPulse(GuideDirection dir, int msecs); 0139 0140 // Parking 0141 bool canPark(); 0142 bool isParked() 0143 { 0144 return m_ParkStatus == PARK_PARKED; 0145 } 0146 bool canCustomPark() 0147 { 0148 return m_hasCustomParking; 0149 } 0150 bool sendParkingOptionCommand(ParkOptionCommand command); 0151 0152 // Status 0153 ParkStatus parkStatus() 0154 { 0155 return m_ParkStatus; 0156 } 0157 0158 Status status(INumberVectorProperty *nvp); 0159 Status status(); 0160 const QString statusString(Status status, bool translated = true) const; 0161 0162 // Altitude Limits 0163 void setAltLimits(double minAltitude, double maxAltitude); 0164 0165 // Alignment Model 0166 bool setAlignmentModelEnabled(bool enable); 0167 bool clearAlignmentModel(); 0168 bool clearParking(); 0169 bool hasAlignmentModel() 0170 { 0171 return m_hasAlignmentModel; 0172 } 0173 0174 // Slew Rates 0175 bool hasSlewRates() 0176 { 0177 return m_hasSlewRates; 0178 } 0179 QStringList slewRates() 0180 { 0181 return m_slewRates; 0182 } 0183 int getSlewRate() const; 0184 0185 // Pier side 0186 PierSide pierSide() const 0187 { 0188 return m_PierSide; 0189 } 0190 0191 // Satellite tracking 0192 bool canTrackSatellite() 0193 { 0194 return m_canTrackSatellite; 0195 } 0196 0197 /** 0198 * @short Tracks satellite on provided TLE, initial epoch for trajectory calculation and window in minutes 0199 * 0200 * This function needs a Two-Line-Element and a time window in the form of an initial point and a 0201 * number of minutes on which the trajectory should start. The function was developed wiht the lx200 0202 * in mind. If the trajectory has already started, the current time and a window of 1min are sufficient. 0203 * 0204 * @param tle Two-line-element. 0205 * @param satPassStart Start time of the trajectory calculation 0206 * @param satPassEnd End time of the trajectory calculation 0207 */ 0208 bool setSatelliteTLEandTrack(QString tle, const KStarsDateTime satPassStart, const KStarsDateTime satPassEnd); 0209 0210 /** 0211 * @brief Hour angle of the current coordinates 0212 */ 0213 const dms hourAngle() const; 0214 0215 const SkyPoint ¤tCoordinates() const 0216 { 0217 return currentCoords; 0218 } 0219 0220 /** 0221 * @brief stopTimers Stop timers to prevent timing race condition when device is unavailable 0222 * and timer is still invoked. 0223 */ 0224 void stopTimers(); 0225 0226 void centerLock(); 0227 void centerUnlock(); 0228 void find(); 0229 void setCustomParking(SkyPoint *coords = nullptr); 0230 0231 protected: 0232 /** 0233 * @brief Send the coordinates to the mount's INDI driver. Due to the INDI implementation, this 0234 * function is shared for syncing, slewing and other (partly scope specific) functions like the 0235 * setting parking position. The interpretation of the coordinates depends in the setting of other 0236 * INDI switches for slewing, synching, tracking etc. 0237 * @param ScopeTarget target coordinates 0238 * @return true if sending the coordinates succeeded 0239 */ 0240 bool sendCoords(SkyPoint *ScopeTarget); 0241 0242 /** 0243 * @brief Check whether sending new coordinates will result into a slew 0244 */ 0245 bool slewDefined(); 0246 0247 /** 0248 * @brief Helper function to update the J2000 coordinates of a sky point from its JNow coordinates 0249 * @param coords sky point with correct JNow values in RA and DEC 0250 */ 0251 void updateJ2000Coordinates(SkyPoint *coords); 0252 0253 /** 0254 * @brief updateParkStatus Updating parking status by checking the TELESCOPE_PARK property. 0255 */ 0256 void updateParkStatus(); 0257 0258 /** 0259 * @brief updateTarget update target position from {@see currentPosition} and 0260 * (if not pointing into the empty sky) also the target name. 0261 */ 0262 void updateTarget(); 0263 0264 public slots: 0265 bool abort(); 0266 bool park(); 0267 bool unpark(); 0268 bool setSlewRate(int index); 0269 bool setTrackEnabled(bool enable); 0270 bool setCustomTrackRate(double raRate, double deRate); 0271 bool setTrackMode(uint8_t index); 0272 0273 signals: 0274 /** 0275 * @brief The mount has finished the slew to a new target. 0276 * @param currentCoords exact position where the mount is positioned 0277 */ 0278 void newTarget(SkyPoint ¤tCoords); 0279 0280 /** 0281 * @brief The mount has finished the slew to a new target. 0282 * @param Name Name of object, if any, the mount is positioned at. 0283 */ 0284 void newTargetName(const QString &name); 0285 /** 0286 * @brief Change in the mount status. 0287 */ 0288 void newStatus(ISD::Mount::Status status); 0289 /** 0290 * @brief Update event with the current telescope position 0291 * @param position mount position. Independent from the mount type, 0292 * the EQ coordinates(both JNow and J2000) as well as the alt/az values are filled. 0293 * @param pierside for GEMs report the pier side the scope is currently (PierSide::PIER_WEST means 0294 * the mount is on the western side of the pier pointing east of the meridian). 0295 * @param ha current hour angle 0296 */ 0297 void newCoords(const SkyPoint &position, const PierSide pierside, const dms &ha); 0298 void newParkStatus(ISD::ParkStatus status); 0299 void slewRateChanged(int rate); 0300 void pierSideChanged(PierSide side); 0301 void axisReversed(INDI_EQ_AXIS axis, bool reversed); 0302 0303 private: 0304 SkyPoint currentCoords; 0305 double minAlt {0}, maxAlt = 90; 0306 ParkStatus m_ParkStatus = PARK_UNKNOWN; 0307 IPState EqCoordPreviousState {IPS_IDLE}; 0308 QTimer centerLockTimer; 0309 QTimer updateCoordinatesTimer; 0310 SkyObject *currentObject = nullptr; 0311 bool inManualMotion = false; 0312 bool inCustomParking = false; 0313 IPState NSPreviousState = IPS_IDLE; 0314 IPState WEPreviousState = IPS_IDLE; 0315 PierSide m_PierSide = PIER_UNKNOWN; 0316 0317 KStarsDateTime g_satPassStart; 0318 KStarsDateTime g_satPassEnd; 0319 0320 QMap<TrackModes, uint8_t> TrackMap; 0321 TrackModes currentTrackMode { TRACK_SIDEREAL }; 0322 0323 bool m_hasAlignmentModel = { false }; 0324 bool m_canControlTrack = { false }; 0325 bool m_canGoto { false}; 0326 bool m_canFlip { false}; 0327 bool m_canSync { false}; 0328 bool m_canAbort { false }; 0329 bool m_canTrackSatellite { false }; 0330 bool m_TLEIsSetForTracking { false }; 0331 bool m_windowIsSetForTracking { false }; 0332 bool m_hasTrackModes { false}; 0333 bool m_hasCustomTrackRate { false}; 0334 bool m_hasCustomParking { false }; 0335 bool m_hasSlewRates { false }; 0336 bool m_isJ2000 { false }; 0337 bool m_hasEquatorialCoordProperty { false }; 0338 QStringList m_slewRates; 0339 }; 0340 } 0341 0342 Q_DECLARE_METATYPE(ISD::Mount::Status) 0343 QDBusArgument &operator<<(QDBusArgument &argument, const ISD::Mount::Status &source); 0344 const QDBusArgument &operator>>(const QDBusArgument &argument, ISD::Mount::Status &dest); 0345 0346 Q_DECLARE_METATYPE(ISD::Mount::PierSide) 0347 QDBusArgument &operator<<(QDBusArgument &argument, const ISD::Mount::PierSide &source); 0348 const QDBusArgument &operator>>(const QDBusArgument &argument, ISD::Mount::PierSide &dest);