1 /* 2 SPDX-FileCopyrightText: 2012 Jasem Mutlaq <mutlaqja@ikarustech.com> 3 4 SPDX-License-Identifier: GPL-2.0-or-later 5 */ 6 7 #pragma once 8 9 #include <QDBusArgument> 10 #include <QTimer> 11 12 #include "indistd.h" 13 #include "skypoint.h" 14 15 class SkyObject; 16 17 namespace ISD 18 { 19 /** 20 * @class Telescope 21 * device handle controlling telescope. It can slew and sync to a specific sky point and supports all standard properties with INDI 22 * telescope device. 23 * 24 * @author Jasem Mutlaq 25 */ 26 class Telescope : public DeviceDecorator 27 { 28 Q_OBJECT 29 30 public: 31 explicit Telescope(GDInterface *iPtr); 32 virtual ~Telescope() override = default; 33 34 typedef enum { MOTION_NORTH, MOTION_SOUTH } TelescopeMotionNS; 35 typedef enum { MOTION_WEST, MOTION_EAST } TelescopeMotionWE; 36 typedef enum { MOTION_START, MOTION_STOP } TelescopeMotionCommand; 37 typedef enum { PIER_UNKNOWN = -1, PIER_WEST = 0, PIER_EAST = 1 } PierSide; 38 typedef enum 39 { 40 MOUNT_IDLE, 41 MOUNT_MOVING, 42 MOUNT_SLEWING, 43 MOUNT_TRACKING, 44 MOUNT_PARKING, 45 MOUNT_PARKED, 46 MOUNT_ERROR 47 } Status; 48 typedef enum { PARK_OPTION_CURRENT, PARK_OPTION_DEFAULT, PARK_OPTION_WRITE_DATA } ParkOptionCommand; 49 typedef enum { TRACK_SIDEREAL, TRACK_SOLAR, TRACK_LUNAR, TRACK_CUSTOM } TrackModes; 50 51 void registerProperty(INDI::Property prop) override; 52 void processSwitch(ISwitchVectorProperty *svp) override; 53 void processText(ITextVectorProperty *tvp) override; 54 void processNumber(INumberVectorProperty *nvp) override; 55 getType()56 DeviceFamily getType() override 57 { 58 return dType; 59 } 60 61 // Coordinates 62 bool getEqCoords(double *ra, double *dec); isJ2000()63 bool isJ2000() 64 { 65 return m_isJ2000; 66 } 67 68 // Slew 69 bool Slew(SkyPoint *ScopeTarget); 70 bool Slew(double ra, double dec); canGoto()71 bool canGoto() 72 { 73 return m_canGoto; 74 } 75 76 // Sync 77 bool Sync(SkyPoint *ScopeTarget); 78 bool Sync(double ra, double dec); canSync()79 bool canSync() 80 { 81 return m_canSync; 82 } 83 84 // Tracking canControlTrack()85 bool canControlTrack() const 86 { 87 return m_canControlTrack; 88 } 89 bool isTracking(); 90 91 // Track Mode hasTrackModes()92 bool hasTrackModes() const 93 { 94 return m_hasTrackModes; 95 } 96 bool getTrackMode(uint8_t &index); 97 98 // Custom Track Rate hasCustomTrackRate()99 bool hasCustomTrackRate() const 100 { 101 return m_hasTrackModes; 102 } 103 bool getCustomTrackRate(double &raRate, double &deRate); 104 105 // Motion 106 bool MoveNS(TelescopeMotionNS dir, TelescopeMotionCommand cmd); 107 bool StopNS(); 108 bool MoveWE(TelescopeMotionWE dir, TelescopeMotionCommand cmd); 109 bool StopWE(); 110 bool isSlewing(); 111 bool isInMotion(); canAbort()112 bool canAbort() 113 { 114 return m_canAbort; 115 } 116 QString getManualMotionString() const; 117 118 // Guiding 119 bool canGuide(); 120 bool doPulse(GuideDirection ra_dir, int ra_msecs, GuideDirection dec_dir, int dec_msecs); 121 bool doPulse(GuideDirection dir, int msecs); 122 123 // Parking 124 bool canPark(); isParked()125 bool isParked() 126 { 127 return m_ParkStatus == PARK_PARKED; 128 } canCustomPark()129 bool canCustomPark() 130 { 131 return m_hasCustomParking; 132 } 133 bool sendParkingOptionCommand(ParkOptionCommand command); 134 135 // Status parkStatus()136 ParkStatus parkStatus() 137 { 138 return m_ParkStatus; 139 } 140 141 Status status(INumberVectorProperty *nvp); 142 Status status(); 143 const QString getStatusString(Status status); 144 145 // Altitude Limits 146 void setAltLimits(double minAltitude, double maxAltitude); 147 148 // Alignment Model 149 bool setAlignmentModelEnabled(bool enable); 150 bool clearAlignmentModel(); 151 bool clearParking(); hasAlignmentModel()152 bool hasAlignmentModel() 153 { 154 return m_hasAlignmentModel; 155 } 156 157 // Slew Rates hasSlewRates()158 bool hasSlewRates() 159 { 160 return m_hasSlewRates; 161 } slewRates()162 QStringList slewRates() 163 { 164 return m_slewRates; 165 } 166 int getSlewRate() const; 167 168 // Pier side pierSide()169 PierSide pierSide() const 170 { 171 return m_PierSide; 172 } 173 174 // Satellite tracking canTrackSatellite()175 bool canTrackSatellite() 176 { 177 return m_canTrackSatellite; 178 } 179 180 /** 181 * @short Tracks satellite on provided TLE, initial epoch for trajectory calculation and window in minutes 182 * 183 * This function needs a Two-Line-Element and a time window in the form of an initial point and a 184 * number of minutes on which the trajectory should start. The function was developed wiht the lx200 185 * in mind. If the trajectory has already started, the current time and a window of 1min are sufficient. 186 * 187 * @param tle Two-line-element. 188 * @param satPassStart Start time of the trajectory calculation 189 * @param satPassEnd End time of the trajectory calculation 190 */ 191 bool setSatelliteTLEandTrack(QString tle, const KStarsDateTime satPassStart, const KStarsDateTime satPassEnd); 192 193 /** 194 * @brief Hour angle of the current coordinates 195 */ 196 const dms hourAngle() const; 197 currentCoordinates()198 const SkyPoint ¤tCoordinates() const 199 { 200 return currentCoords; 201 } 202 203 204 protected: 205 /** 206 * @brief Send the coordinates to the mount's INDI driver. Due to the INDI implementation, this 207 * function is shared for syncing, slewing and other (partly scope specific) functions like the 208 * setting parking position. The interpretation of the coordinates depends in the setting of other 209 * INDI switches for slewing, synching, tracking etc. 210 * @param ScopeTarget target coordinates 211 * @return true if sending the coordinates succeeded 212 */ 213 bool sendCoords(SkyPoint *ScopeTarget); 214 215 /** 216 * @brief Check whether sending new coordinates will result into a slew 217 */ 218 bool slewDefined(); 219 220 /** 221 * @brief Helper function to update the J2000 coordinates of a sky point from its JNow coordinates 222 * @param coords sky point with correct JNow values in RA and DEC 223 */ 224 void updateJ2000Coordinates(SkyPoint *coords); 225 226 public slots: 227 virtual bool runCommand(int command, void *ptr = nullptr) override; 228 bool Abort(); 229 bool Park(); 230 bool UnPark(); 231 bool setSlewRate(int index); 232 bool setTrackEnabled(bool enable); 233 bool setCustomTrackRate(double raRate, double deRate); 234 bool setTrackMode(uint8_t index); 235 236 signals: 237 /** 238 * @brief The mount has finished the slew to a new target. 239 * @param currentObject object close to the position the mount is pointing to 240 * @param currentCoords exact position where the mount is positioned 241 */ 242 void newTarget(SkyObject ¤tObject, SkyPoint ¤tCoords); 243 /** 244 * @brief Change in the mount status. 245 */ 246 void newStatus(ISD::Telescope::Status status); 247 /** 248 * @brief Update event with the current telescope position 249 * @param position mount position. Independent from the mount type, 250 * the EQ coordinates(both JNow and J2000) as well as the alt/az values are filled. 251 * @param pierside for GEMs report the pier side the scope is currently (PierSide::PIER_WEST means 252 * the mount is on the western side of the pier pointing east of the meridian). 253 * @param ha current hour angle 254 */ 255 void newCoords(const SkyPoint &position, const PierSide pierside, const dms &ha); 256 void newParkStatus(ISD::ParkStatus status); 257 void slewRateChanged(int rate); 258 void pierSideChanged(PierSide side); 259 void ready(); 260 261 private: 262 SkyPoint currentCoords; 263 double minAlt = 0, maxAlt = 90; 264 ParkStatus m_ParkStatus = PARK_UNKNOWN; 265 IPState EqCoordPreviousState; 266 QTimer centerLockTimer; 267 QTimer readyTimer; 268 SkyObject *currentObject = nullptr; 269 bool inManualMotion = false; 270 bool inCustomParking = false; 271 IPState NSPreviousState = IPS_IDLE; 272 IPState WEPreviousState = IPS_IDLE; 273 PierSide m_PierSide = PIER_UNKNOWN; 274 275 KStarsDateTime g_satPassStart; 276 KStarsDateTime g_satPassEnd; 277 278 QMap<TrackModes, uint8_t> TrackMap; 279 TrackModes currentTrackMode { TRACK_SIDEREAL }; 280 281 bool m_hasAlignmentModel = { false }; 282 bool m_canControlTrack = { false }; 283 bool m_canGoto { false}; 284 bool m_canSync { false}; 285 bool m_canAbort { false }; 286 bool m_canTrackSatellite { false }; 287 bool m_TLEIsSetForTracking { false }; 288 bool m_windowIsSetForTracking { false }; 289 bool m_hasTrackModes { false}; 290 bool m_hasCustomTrackRate { false}; 291 bool m_hasCustomParking { false }; 292 bool m_hasSlewRates { false }; 293 bool m_isJ2000 { false }; 294 QStringList m_slewRates; 295 }; 296 } 297 298 Q_DECLARE_METATYPE(ISD::Telescope::Status) 299 QDBusArgument &operator<<(QDBusArgument &argument, const ISD::Telescope::Status &source); 300 const QDBusArgument &operator>>(const QDBusArgument &argument, ISD::Telescope::Status &dest); 301 302 Q_DECLARE_METATYPE(ISD::Telescope::PierSide) 303 QDBusArgument &operator<<(QDBusArgument &argument, const ISD::Telescope::PierSide &source); 304 const QDBusArgument &operator>>(const QDBusArgument &argument, ISD::Telescope::PierSide &dest); 305