Kstars

indimount.h
1 /*
2  SPDX-FileCopyrightText: 2012 Jasem Mutlaq <[email protected]>
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 "indiconcretedevice.h"
13 #include "skypoint.h"
14 
15 class SkyObject;
16 
17 namespace ISD
18 {
19 /**
20  * @class Mount
21  * device handle controlling Mounts. 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 Mount : public ConcreteDevice
27 {
28  Q_OBJECT
29 
30  public:
31  explicit Mount(GenericDevice *parent);
32  virtual ~Mount() override = default;
33 
34  typedef enum { MOTION_NORTH, MOTION_SOUTH } VerticalMotion;
35  typedef enum { MOTION_WEST, MOTION_EAST } HorizontalMotion;
36  typedef enum { MOTION_START, MOTION_STOP } MotionCommand;
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 
52  static const QList<const char *> mountStates;
53 
54  void registerProperty(INDI::Property prop) override;
55  void processSwitch(ISwitchVectorProperty *svp) override;
56  void processText(ITextVectorProperty *tvp) override;
57  void processNumber(INumberVectorProperty *nvp) override;
58 
59  // Coordinates
60  bool getEqCoords(double *ra, double *dec);
61  bool isJ2000()
62  {
63  return m_isJ2000;
64  }
65 
66  // Slew
67  bool Slew(SkyPoint *ScopeTarget);
68  bool Slew(double ra, double dec);
69  bool canGoto()
70  {
71  return m_canGoto;
72  }
73 
74  // Sync
75  bool Sync(SkyPoint *ScopeTarget);
76  bool Sync(double ra, double dec);
77  bool canSync()
78  {
79  return m_canSync;
80  }
81 
82  // Tracking
83  bool canControlTrack() const
84  {
85  return m_canControlTrack;
86  }
87  bool isTracking();
88 
89  // Track Mode
90  bool hasTrackModes() const
91  {
92  return m_hasTrackModes;
93  }
94  bool getTrackMode(uint8_t &index);
95 
96  // Custom Track Rate
97  bool hasCustomTrackRate() const
98  {
99  return m_hasTrackModes;
100  }
101  bool getCustomTrackRate(double &raRate, double &deRate);
102 
103  // Motion
104  bool MoveNS(VerticalMotion dir, MotionCommand cmd);
105  bool StopNS();
106  bool MoveWE(HorizontalMotion dir, MotionCommand cmd);
107  bool StopWE();
108  bool isReversed(INDI_EQ_AXIS axis);
109  bool setReversedEnabled(INDI_EQ_AXIS axis, bool enabled);
110  bool isSlewing();
111  bool isInMotion();
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();
125  bool isParked()
126  {
127  return m_ParkStatus == PARK_PARKED;
128  }
129  bool canCustomPark()
130  {
131  return m_hasCustomParking;
132  }
133  bool sendParkingOptionCommand(ParkOptionCommand command);
134 
135  // Status
136  ParkStatus parkStatus()
137  {
138  return m_ParkStatus;
139  }
140 
141  Status status(INumberVectorProperty *nvp);
142  Status status();
143  const QString statusString(Status status, bool translated = true) const;
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();
152  bool hasAlignmentModel()
153  {
154  return m_hasAlignmentModel;
155  }
156 
157  // Slew Rates
158  bool hasSlewRates()
159  {
160  return m_hasSlewRates;
161  }
162  QStringList slewRates()
163  {
164  return m_slewRates;
165  }
166  int getSlewRate() const;
167 
168  // Pier side
169  PierSide pierSide() const
170  {
171  return m_PierSide;
172  }
173 
174  // Satellite tracking
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 
198  const SkyPoint &currentCoordinates() const
199  {
200  return currentCoords;
201  }
202 
203  /**
204  * @brief stopTimers Stop timers to prevent timing race condition when device is unavailable
205  * and timer is still invoked.
206  */
207  void stopTimers();
208 
209  void centerLock();
210  void centerUnlock();
211  void find();
212  void setCustomParking(SkyPoint *coords = nullptr);
213 
214  protected:
215  /**
216  * @brief Send the coordinates to the mount's INDI driver. Due to the INDI implementation, this
217  * function is shared for syncing, slewing and other (partly scope specific) functions like the
218  * setting parking position. The interpretation of the coordinates depends in the setting of other
219  * INDI switches for slewing, synching, tracking etc.
220  * @param ScopeTarget target coordinates
221  * @return true if sending the coordinates succeeded
222  */
223  bool sendCoords(SkyPoint *ScopeTarget);
224 
225  /**
226  * @brief Check whether sending new coordinates will result into a slew
227  */
228  bool slewDefined();
229 
230  /**
231  * @brief Helper function to update the J2000 coordinates of a sky point from its JNow coordinates
232  * @param coords sky point with correct JNow values in RA and DEC
233  */
234  void updateJ2000Coordinates(SkyPoint *coords);
235 
236  /**
237  * @brief updateParkStatus Updating parking status by checking the TELESCOPE_PARK property.
238  */
239  void updateParkStatus();
240 
241  public slots:
242  bool abort();
243  bool park();
244  bool unpark();
245  bool setSlewRate(int index);
246  bool setTrackEnabled(bool enable);
247  bool setCustomTrackRate(double raRate, double deRate);
248  bool setTrackMode(uint8_t index);
249 
250  signals:
251  /**
252  * @brief The mount has finished the slew to a new target.
253  * @param currentCoords exact position where the mount is positioned
254  */
255  void newTarget(SkyPoint &currentCoords);
256 
257  /**
258  * @brief The mount has finished the slew to a new target.
259  * @param Name Name of object, if any, the mount is positioned at.
260  */
261  void newTargetName(const QString &name);
262  /**
263  * @brief Change in the mount status.
264  */
265  void newStatus(ISD::Mount::Status status);
266  /**
267  * @brief Update event with the current telescope position
268  * @param position mount position. Independent from the mount type,
269  * the EQ coordinates(both JNow and J2000) as well as the alt/az values are filled.
270  * @param pierside for GEMs report the pier side the scope is currently (PierSide::PIER_WEST means
271  * the mount is on the western side of the pier pointing east of the meridian).
272  * @param ha current hour angle
273  */
274  void newCoords(const SkyPoint &position, const PierSide pierside, const dms &ha);
275  void newParkStatus(ISD::ParkStatus status);
276  void slewRateChanged(int rate);
277  void pierSideChanged(PierSide side);
278  void axisReversed(INDI_EQ_AXIS axis, bool reversed);
279 
280  private:
281  SkyPoint currentCoords;
282  double minAlt {0}, maxAlt = 90;
283  ParkStatus m_ParkStatus = PARK_UNKNOWN;
284  IPState EqCoordPreviousState {IPS_IDLE};
285  QTimer centerLockTimer;
286  QTimer updateCoordinatesTimer;
287  SkyObject *currentObject = nullptr;
288  bool inManualMotion = false;
289  bool inCustomParking = false;
290  IPState NSPreviousState = IPS_IDLE;
291  IPState WEPreviousState = IPS_IDLE;
292  PierSide m_PierSide = PIER_UNKNOWN;
293 
294  KStarsDateTime g_satPassStart;
295  KStarsDateTime g_satPassEnd;
296 
297  QMap<TrackModes, uint8_t> TrackMap;
298  TrackModes currentTrackMode { TRACK_SIDEREAL };
299 
300  bool m_hasAlignmentModel = { false };
301  bool m_canControlTrack = { false };
302  bool m_canGoto { false};
303  bool m_canSync { false};
304  bool m_canAbort { false };
305  bool m_canTrackSatellite { false };
306  bool m_TLEIsSetForTracking { false };
307  bool m_windowIsSetForTracking { false };
308  bool m_hasTrackModes { false};
309  bool m_hasCustomTrackRate { false};
310  bool m_hasCustomParking { false };
311  bool m_hasSlewRates { false };
312  bool m_isJ2000 { false };
313  bool m_hasEquatorialCoordProperty { false };
314  QStringList m_slewRates;
315 };
316 }
317 
318 Q_DECLARE_METATYPE(ISD::Mount::Status)
319 QDBusArgument &operator<<(QDBusArgument &argument, const ISD::Mount::Status &source);
320 const QDBusArgument &operator>>(const QDBusArgument &argument, ISD::Mount::Status &dest);
321 
322 Q_DECLARE_METATYPE(ISD::Mount::PierSide)
323 QDBusArgument &operator<<(QDBusArgument &argument, const ISD::Mount::PierSide &source);
324 const QDBusArgument &operator>>(const QDBusArgument &argument, ISD::Mount::PierSide &dest);
Q_OBJECTQ_OBJECT
bool setSatelliteTLEandTrack(QString tle, const KStarsDateTime satPassStart, const KStarsDateTime satPassEnd)
Tracks satellite on provided TLE, initial epoch for trajectory calculation and window in minutes.
Definition: indimount.cpp:1205
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
void stopTimers()
stopTimers Stop timers to prevent timing race condition when device is unavailable and timer is still...
Definition: indimount.cpp:1506
Stores dms coordinates for a point in the sky. for converting between coordinate systems.
Definition: skypoint.h:44
void newTarget(SkyPoint &currentCoords)
The mount has finished the slew to a new target.
void updateParkStatus()
updateParkStatus Updating parking status by checking the TELESCOPE_PARK property.
Definition: indimount.cpp:415
void newCoords(const SkyPoint &position, const PierSide pierside, const dms &ha)
Update event with the current telescope position.
const dms hourAngle() const
Hour angle of the current coordinates.
Definition: indimount.cpp:1480
bool slewDefined()
Check whether sending new coordinates will result into a slew.
Definition: indimount.cpp:851
void newTargetName(const QString &name)
The mount has finished the slew to a new target.
void updateJ2000Coordinates(SkyPoint *coords)
Helper function to update the J2000 coordinates of a sky point from its JNow coordinates.
Definition: indimount.cpp:187
An angle, stored as degrees, but expressible in many ways.
Definition: dms.h:37
void newStatus(ISD::Mount::Status status)
Change in the mount status.
The ConcreteDevice class.
QDebug operator<<(QDebug d, const QCPVector2D &vec)
Definition: qcustomplot.h:450
bool sendCoords(SkyPoint *ScopeTarget)
Send the coordinates to the mount's INDI driver.
Definition: indimount.cpp:615
QDataStream & operator>>(QDataStream &in, KDateTime &dateTime)
Information about an object in the sky.
Definition: skyobject.h:41
QObject * parent() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Wed Sep 28 2022 03:58:10 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.