Kstars

indimount.h
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 "indiconcretedevice.h"
13#include "skypoint.h"
14
15class SkyObject;
16
17namespace 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 */
26class Mount : public ConcreteDevice
27{
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 static QString pierSideStateString(PierSide ps)
39 {
40 switch (ps)
41 {
42 case ISD::Mount::PierSide::PIER_EAST:
43 return "Pier Side: East (pointing West)";
44 case ISD::Mount::PierSide::PIER_WEST:
45 return "Pier Side: West (pointing East)";
46 default:
47 return "Pier Side: Unknown";
48 }
49 }
50
51 typedef enum
52 {
53 MOUNT_IDLE,
54 MOUNT_MOVING,
55 MOUNT_SLEWING,
56 MOUNT_TRACKING,
57 MOUNT_PARKING,
58 MOUNT_PARKED,
59 MOUNT_ERROR
60 } Status;
61 typedef enum { PARK_OPTION_CURRENT, PARK_OPTION_DEFAULT, PARK_OPTION_WRITE_DATA } ParkOptionCommand;
62 typedef enum { TRACK_SIDEREAL, TRACK_SOLAR, TRACK_LUNAR, TRACK_CUSTOM } TrackModes;
63
64
65 static const QList<const char *> mountStates;
66
67 void registerProperty(INDI::Property prop) override;
68 void processSwitch(INDI::Property prop) override;
69 void processText(INDI::Property prop) override;
70 void processNumber(INDI::Property prop) override;
71
72 // Coordinates
73 bool getEqCoords(double *ra, double *dec);
74 bool isJ2000()
75 {
76 return m_isJ2000;
77 }
78
79 // Slew
80 bool Slew(SkyPoint *ScopeTarget, bool flip=false);
81 bool Slew(double ra, double dec, bool flip=false);
82 bool canGoto()
83 {
84 return m_canGoto;
85 }
86 bool canFlip()
87 {
88 return m_canFlip;
89 }
90
91 // Sync
92 bool Sync(SkyPoint *ScopeTarget);
93 bool Sync(double ra, double dec);
94 bool canSync()
95 {
96 return m_canSync;
97 }
98
99 // Tracking
100 bool canControlTrack() const
101 {
102 return m_canControlTrack;
103 }
104 bool isTracking();
105
106 // Track Mode
107 bool hasTrackModes() const
108 {
109 return m_hasTrackModes;
110 }
111 bool getTrackMode(uint8_t &index);
112
113 // Custom Track Rate
114 bool hasCustomTrackRate() const
115 {
116 return m_hasTrackModes;
117 }
118 bool getCustomTrackRate(double &raRate, double &deRate);
119
120 // Motion
121 bool MoveNS(VerticalMotion dir, MotionCommand cmd);
122 bool StopNS();
123 bool MoveWE(HorizontalMotion dir, MotionCommand cmd);
124 bool StopWE();
125 bool isReversed(INDI_EQ_AXIS axis);
126 bool setReversedEnabled(INDI_EQ_AXIS axis, bool enabled);
127 bool isSlewing();
128 bool isInMotion();
129 bool canAbort()
130 {
131 return m_canAbort;
132 }
133 QString getManualMotionString() const;
134
135 // Guiding
136 bool canGuide();
137 bool doPulse(GuideDirection ra_dir, int ra_msecs, GuideDirection dec_dir, int dec_msecs);
138 bool doPulse(GuideDirection dir, int msecs);
139
140 // Parking
141 bool canPark();
142 bool isParked()
143 {
144 return m_ParkStatus == PARK_PARKED;
145 }
146 bool canCustomPark()
147 {
148 return m_hasCustomParking;
149 }
150 bool sendParkingOptionCommand(ParkOptionCommand command);
151
152 // Status
153 ParkStatus parkStatus()
154 {
155 return m_ParkStatus;
156 }
157
158 Status status(INumberVectorProperty *nvp);
159 Status status();
160 const QString statusString(Status status, bool translated = true) const;
161
162 // Altitude Limits
163 void setAltLimits(double minAltitude, double maxAltitude);
164
165 // Alignment Model
166 bool setAlignmentModelEnabled(bool enable);
167 bool clearAlignmentModel();
168 bool clearParking();
169 bool hasAlignmentModel()
170 {
171 return m_hasAlignmentModel;
172 }
173
174 // Slew Rates
175 bool hasSlewRates()
176 {
177 return m_hasSlewRates;
178 }
179 QStringList slewRates()
180 {
181 return m_slewRates;
182 }
183 int getSlewRate() const;
184
185 // Pier side
186 PierSide pierSide() const
187 {
188 return m_PierSide;
189 }
190
191 // Satellite tracking
192 bool canTrackSatellite()
193 {
194 return m_canTrackSatellite;
195 }
196
197 /**
198 * @short Tracks satellite on provided TLE, initial epoch for trajectory calculation and window in minutes
199 *
200 * This function needs a Two-Line-Element and a time window in the form of an initial point and a
201 * number of minutes on which the trajectory should start. The function was developed wiht the lx200
202 * in mind. If the trajectory has already started, the current time and a window of 1min are sufficient.
203 *
204 * @param tle Two-line-element.
205 * @param satPassStart Start time of the trajectory calculation
206 * @param satPassEnd End time of the trajectory calculation
207 */
209
210 /**
211 * @brief Hour angle of the current coordinates
212 */
213 const dms hourAngle() const;
214
215 const SkyPoint &currentCoordinates() const
216 {
217 return currentCoords;
218 }
219
220 /**
221 * @brief stopTimers Stop timers to prevent timing race condition when device is unavailable
222 * and timer is still invoked.
223 */
224 void stopTimers();
225
226 void centerLock();
227 void centerUnlock();
228 void find();
229 void setCustomParking(SkyPoint *coords = nullptr);
230
231 protected:
232 /**
233 * @brief Send the coordinates to the mount's INDI driver. Due to the INDI implementation, this
234 * function is shared for syncing, slewing and other (partly scope specific) functions like the
235 * setting parking position. The interpretation of the coordinates depends in the setting of other
236 * INDI switches for slewing, synching, tracking etc.
237 * @param ScopeTarget target coordinates
238 * @return true if sending the coordinates succeeded
239 */
241
242 /**
243 * @brief Check whether sending new coordinates will result into a slew
244 */
245 bool slewDefined();
246
247 /**
248 * @brief Helper function to update the J2000 coordinates of a sky point from its JNow coordinates
249 * @param coords sky point with correct JNow values in RA and DEC
250 */
251 void updateJ2000Coordinates(SkyPoint *coords);
252
253 /**
254 * @brief updateParkStatus Updating parking status by checking the TELESCOPE_PARK property.
255 */
256 void updateParkStatus();
257
258 /**
259 * @brief updateTarget update target position from {@see currentPosition} and
260 * (if not pointing into the empty sky) also the target name.
261 */
262 void updateTarget();
263
264 public slots:
265 bool abort();
266 bool park();
267 bool unpark();
268 bool setSlewRate(int index);
269 bool setTrackEnabled(bool enable);
270 bool setCustomTrackRate(double raRate, double deRate);
271 bool setTrackMode(uint8_t index);
272
273 signals:
274 /**
275 * @brief The mount has finished the slew to a new target.
276 * @param currentCoords exact position where the mount is positioned
277 */
278 void newTarget(SkyPoint &currentCoords);
279
280 /**
281 * @brief The mount has finished the slew to a new target.
282 * @param Name Name of object, if any, the mount is positioned at.
283 */
284 void newTargetName(const QString &name);
285 /**
286 * @brief Change in the mount status.
287 */
288 void newStatus(ISD::Mount::Status status);
289 /**
290 * @brief Update event with the current telescope position
291 * @param position mount position. Independent from the mount type,
292 * the EQ coordinates(both JNow and J2000) as well as the alt/az values are filled.
293 * @param pierside for GEMs report the pier side the scope is currently (PierSide::PIER_WEST means
294 * the mount is on the western side of the pier pointing east of the meridian).
295 * @param ha current hour angle
296 */
297 void newCoords(const SkyPoint &position, const PierSide pierside, const dms &ha);
298 void newParkStatus(ISD::ParkStatus status);
299 void slewRateChanged(int rate);
300 void pierSideChanged(PierSide side);
301 void axisReversed(INDI_EQ_AXIS axis, bool reversed);
302
303 private:
304 SkyPoint currentCoords;
305 double minAlt {0}, maxAlt = 90;
306 ParkStatus m_ParkStatus = PARK_UNKNOWN;
307 IPState EqCoordPreviousState {IPS_IDLE};
308 QTimer centerLockTimer;
309 QTimer updateCoordinatesTimer;
310 SkyObject *currentObject = nullptr;
311 bool inManualMotion = false;
312 bool inCustomParking = false;
313 IPState NSPreviousState = IPS_IDLE;
314 IPState WEPreviousState = IPS_IDLE;
315 PierSide m_PierSide = PIER_UNKNOWN;
316
317 KStarsDateTime g_satPassStart;
318 KStarsDateTime g_satPassEnd;
319
321 TrackModes currentTrackMode { TRACK_SIDEREAL };
322
323 bool m_hasAlignmentModel = { false };
324 bool m_canControlTrack = { false };
325 bool m_canGoto { false};
326 bool m_canFlip { false};
327 bool m_canSync { false};
328 bool m_canAbort { false };
329 bool m_canTrackSatellite { false };
330 bool m_TLEIsSetForTracking { false };
331 bool m_windowIsSetForTracking { false };
332 bool m_hasTrackModes { false};
333 bool m_hasCustomTrackRate { false};
334 bool m_hasCustomParking { false };
335 bool m_hasSlewRates { false };
336 bool m_isJ2000 { false };
337 bool m_hasEquatorialCoordProperty { false };
338 QStringList m_slewRates;
339};
340}
341
342Q_DECLARE_METATYPE(ISD::Mount::Status)
343QDBusArgument &operator<<(QDBusArgument &argument, const ISD::Mount::Status &source);
344const QDBusArgument &operator>>(const QDBusArgument &argument, ISD::Mount::Status &dest);
345
346Q_DECLARE_METATYPE(ISD::Mount::PierSide)
347QDBusArgument &operator<<(QDBusArgument &argument, const ISD::Mount::PierSide &source);
348const QDBusArgument &operator>>(const QDBusArgument &argument, ISD::Mount::PierSide &dest);
The ConcreteDevice class.
GenericDevice is the Generic Device for INDI devices.
Definition indistd.h:117
device handle controlling Mounts.
Definition indimount.h:27
void updateTarget()
updateTarget update target position from {
void newStatus(ISD::Mount::Status status)
Change in the mount status.
bool slewDefined()
Check whether sending new coordinates will result into a slew.
const dms hourAngle() const
Hour angle of the current coordinates.
void updateJ2000Coordinates(SkyPoint *coords)
Helper function to update the J2000 coordinates of a sky point from its JNow coordinates.
bool sendCoords(SkyPoint *ScopeTarget)
Send the coordinates to the mount's INDI driver.
bool setSatelliteTLEandTrack(QString tle, const KStarsDateTime satPassStart, const KStarsDateTime satPassEnd)
Tracks satellite on provided TLE, initial epoch for trajectory calculation and window in minutes.
void updateParkStatus()
updateParkStatus Updating parking status by checking the TELESCOPE_PARK property.
void stopTimers()
stopTimers Stop timers to prevent timing race condition when device is unavailable and timer is still...
void newTarget(SkyPoint &currentCoords)
The mount has finished the slew to a new target.
void newCoords(const SkyPoint &position, const PierSide pierside, const dms &ha)
Update event with the current telescope position.
void newTargetName(const QString &name)
The mount has finished the slew to a new target.
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
Provides all necessary information about an object in the sky: its coordinates, name(s),...
Definition skyobject.h:42
The sky coordinates of a point in the sky.
Definition skypoint.h:45
An angle, stored as degrees, but expressible in many ways.
Definition dms.h:38
ISD is a collection of INDI Standard Devices.
KCALENDARCORE_EXPORT QDataStream & operator>>(QDataStream &in, const KCalendarCore::Alarm::Ptr &)
Q_OBJECTQ_OBJECT
QObject * parent() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:19:03 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.