Kstars

inditelescopelite.cpp
1/*
2 SPDX-FileCopyrightText: 2012 Jasem Mutlaq <mutlaqja@ikarustech.com>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include <indi/indidevice.h>
8
9#include "Options.h"
10
11#include "clientmanagerlite.h"
12#include "inditelescopelite.h"
13
14#include "kstarslite.h"
15#include "skymaplite.h"
16
17TelescopeLite::TelescopeLite(INDI::BaseDevice *device)
18 : minAlt(-1), maxAlt(-1), IsParked(false), clientManager(KStarsLite::Instance()->clientManagerLite()),
19 baseDevice(device), slewRateIndex(0)
20{
21 setDeviceName(device->getDeviceName());
22 //Whenever slew rate is changed (or once it was initialized) we update it
23 connect(clientManager, &ClientManagerLite::newINDIProperty, this, &TelescopeLite::updateSlewRate);
24 connect(clientManager, &ClientManagerLite::newINDISwitch, this, &TelescopeLite::updateSlewRate);
25}
26
27void TelescopeLite::updateSlewRate(const QString &deviceName, const QString &propName)
28{
29 if (deviceName == baseDevice->getDeviceName() && propName == "TELESCOPE_SLEW_RATE")
30 {
31 auto slewRateSP = baseDevice->getSwitch("TELESCOPE_SLEW_RATE");
32 int index = 0;
33 for (int i = 0; i < slewRateSP->count(); ++i)
34 {
35 if (slewRateSP->at(i).getState() == ISS_ON)
36 {
37 index = i;
38 break;
39 }
40 }
41 m_slewRateLabels.clear();
42 for (int i = 0; i < slewRateSP->count(); ++i)
43 {
44 m_slewRateLabels.push_back(slewRateSP->at(i)->getLabel());
45 }
46 emit slewRateUpdate(index, m_slewRateLabels.size());
47 setSlewRate(index);
48 }
49}
50
51TelescopeLite::~TelescopeLite()
52{
53}
54
55void TelescopeLite::setSlewDecreasable(bool slewDecreasable)
56{
57 if (m_slewDecreasable != slewDecreasable)
58 {
59 m_slewDecreasable = slewDecreasable;
60 emit slewDecreasableChanged(slewDecreasable);
61 }
62}
63
64void TelescopeLite::setSlewIncreasable(bool slewIncreasable)
65{
66 if (m_slewIncreasable != slewIncreasable)
67 {
68 m_slewIncreasable = slewIncreasable;
69 emit slewIncreasableChanged(slewIncreasable);
70 }
71}
72
73void TelescopeLite::setSlewRateLabel(const QString &slewRateLabel)
74{
75 if (m_slewRateLabel != slewRateLabel)
76 {
77 m_slewRateLabel = slewRateLabel;
78 emit slewRateLabelChanged(slewRateLabel);
79 }
80}
81
82void TelescopeLite::setDeviceName(const QString &deviceName)
83{
84 if (m_deviceName != deviceName)
85 {
86 m_deviceName = deviceName;
87 emit deviceNameChanged(deviceName);
88 }
89}
90
91void TelescopeLite::registerProperty(INDI::Property prop)
92{
93 if (prop->isNameMatch("TELESCOPE_INFO"))
94 {
95 auto ti = prop->getNumber();
96
97 if (!ti)
98 return;
99
100 // bool aperture_ok=false, focal_ok=false;
101 // double temp=0;
102 }
103
104 if (prop->isNameMatch("TELESCOPE_PARK"))
105 {
106 auto svp = prop->getSwitch();
107
108 if (svp)
109 {
110 auto sp = svp->findWidgetByName("PARK");
111 if (sp)
112 {
113 IsParked = ((sp->getState() == ISS_ON) && svp->getState() == IPS_OK);
114 }
115 }
116 }
117}
118
119void TelescopeLite::processNumber(INumberVectorProperty *nvp)
120{
121 if (!strcmp(nvp->name, "EQUATORIAL_EOD_COORD"))
122 {
123 INumber *RA = IUFindNumber(nvp, "RA");
124 INumber *DEC = IUFindNumber(nvp, "DEC");
125
126 if (RA == nullptr || DEC == nullptr)
127 return;
128
129 currentCoord.setRA(RA->value);
130 currentCoord.setDec(DEC->value);
131
132 //KStarsLite::Instance()->map()->update();
133
134 //emit numberUpdated(nvp);
135
136 return;
137 }
138
139 if (!strcmp(nvp->name, "EQUATORIAL_COORD"))
140 {
141 INumber *RA = IUFindNumber(nvp, "RA");
142 INumber *DEC = IUFindNumber(nvp, "DEC");
143
144 if (RA == nullptr || DEC == nullptr)
145 return;
146
147 currentCoord.setRA0(RA->value);
148 currentCoord.setDec0(DEC->value);
149 currentCoord.apparentCoord(static_cast<long double>(J2000), KStarsLite::Instance()->data()->ut().djd());
150
151 //KStarsLite::Instance()->map()->update();
152
153 //emit numberUpdated(nvp);
154
155 return;
156 }
157
158 if (!strcmp(nvp->name, "HORIZONTAL_COORD"))
159 {
160 INumber *Az = IUFindNumber(nvp, "AZ");
161 INumber *Alt = IUFindNumber(nvp, "ALT");
162
163 if (Az == nullptr || Alt == nullptr)
164 return;
165
166 currentCoord.setAz(Az->value);
167 currentCoord.setAlt(Alt->value);
168 currentCoord.HorizontalToEquatorial(KStarsLite::Instance()->data()->lst(),
169 KStarsLite::Instance()->data()->geo()->lat());
170
171 //KStarsLite::Instance()->map()->update();
172
173 //emit numberUpdated(nvp);
174
175 return;
176 }
177
178 //DeviceDecorator::processNumber(nvp);
179}
180
181void TelescopeLite::processSwitch(ISwitchVectorProperty *svp)
182{
183 Q_UNUSED(svp);
184 /*if (!strcmp(svp->name, "TELESCOPE_PARK"))
185 {
186 ISwitch *sp = IUFindSwitch(svp, "PARK");
187 if (sp)
188 {
189 IsParked = ( (sp->s == ISS_ON) && svp->s == IPS_OK);
190 }
191
192 //emit switchUpdated(svp);
193
194 return;
195
196 }*/
197}
198
199bool TelescopeLite::canGuide()
200{
201 auto raPulse = baseDevice->getNumber("TELESCOPE_TIMED_GUIDE_WE");
202 auto decPulse = baseDevice->getNumber("TELESCOPE_TIMED_GUIDE_NS");
203
204 return raPulse && decPulse;
205}
206
207bool TelescopeLite::canSync()
208{
209 auto motionSP = baseDevice->getSwitch("ON_COORD_SET");
210
211 if (!motionSP)
212 return false;
213
214 auto syncSW = motionSP->findWidgetByName("SYNC");
215
216 return (syncSW != nullptr);
217}
218
219bool TelescopeLite::canPark()
220{
221 auto parkSP = baseDevice->getSwitch("TELESCOPE_PARK");
222
223 if (!parkSP)
224 return false;
225
226 auto parkSW = parkSP->findWidgetByName("PARK");
227
228 return (parkSW != nullptr);
229}
230
231bool TelescopeLite::isSlewing()
232{
233 auto EqProp = baseDevice->getNumber("EQUATORIAL_EOD_COORD");
234 if (!EqProp)
235 return false;
236
237 return (EqProp->getState() == IPS_BUSY);
238}
239
240bool TelescopeLite::isInMotion()
241{
242 bool inMotion = false;
243 bool inSlew = isSlewing();
244
245 auto movementSP = baseDevice->getSwitch("TELESCOPE_MOTION_NS");
246 if (movementSP)
247 inMotion = (movementSP->getState() == IPS_BUSY);
248
249 movementSP = baseDevice->getSwitch("TELESCOPE_MOTION_WE");
250 if (movementSP)
251 inMotion = ((movementSP->getState() == IPS_BUSY) || inMotion);
252
253 return (inSlew || inMotion);
254}
255
256bool TelescopeLite::sendCoords(SkyPoint *ScopeTarget)
257{
258 INumber *RAEle = nullptr;
259 INumber *DecEle = nullptr;
260 INumber *AzEle = nullptr;
261 INumber *AltEle = nullptr;
262 double currentRA = 0, currentDEC = 0, currentAlt = 0, currentAz = 0, targetAlt = 0;
263 bool useJ2000(false);
264
265 auto EqProp = baseDevice->getNumber("EQUATORIAL_EOD_COORD");
266 if (!EqProp)
267 {
268 // J2000 Property
269 EqProp = baseDevice->getNumber("EQUATORIAL_COORD");
270 if (EqProp)
271 useJ2000 = true;
272 }
273
274 auto HorProp = baseDevice->getNumber("HORIZONTAL_COORD");
275
276 if (EqProp && EqProp->getPermission() == IP_RO)
277 EqProp = nullptr;
278
279 if (HorProp && HorProp->getPermission() == IP_RO)
280 HorProp = nullptr;
281
282 //qDebug() << "Skymap click - RA: " << scope_target->ra().toHMSString() << " DEC: " << scope_target->dec().toDMSString();
283
284 if (EqProp)
285 {
286 RAEle = IUFindNumber(EqProp, "RA");
287 if (!RAEle)
288 return false;
289 DecEle = IUFindNumber(EqProp, "DEC");
290 if (!DecEle)
291 return false;
292
293 //if (useJ2000)
294 //ScopeTarget->apparentCoord( KStars::Instance()->data()->ut().djd(), static_cast<long double>(J2000));
295
296 currentRA = RAEle->value;
297 currentDEC = DecEle->value;
298
299 ScopeTarget->EquatorialToHorizontal(KStarsData::Instance()->lst(), KStarsData::Instance()->geo()->lat());
300 }
301
302 if (HorProp)
303 {
304 AzEle = IUFindNumber(HorProp, "AZ");
305 if (!AzEle)
306 return false;
307 AltEle = IUFindNumber(HorProp, "ALT");
308 if (!AltEle)
309 return false;
310
311 currentAz = AzEle->value;
312 currentAlt = AltEle->value;
313 }
314
315 /* Could not find either properties! */
316 if (EqProp == nullptr && HorProp == nullptr)
317 return false;
318
319 //targetAz = ScopeTarget->az().Degrees();
320 targetAlt = ScopeTarget->altRefracted().Degrees();
321 if (targetAlt < 0)
322 {
323 return false;
324 }
325
326 if (EqProp)
327 {
328 dms ra, de;
329
330 if (useJ2000)
331 {
332 // If we have invalid DEC, then convert coords to J2000
333 if (ScopeTarget->dec0().Degrees() == 180.0)
334 {
335 ScopeTarget->setRA0(ScopeTarget->ra());
336 ScopeTarget->setDec0(ScopeTarget->dec());
337 ScopeTarget->apparentCoord( KStarsLite::Instance()->data()->ut().djd(), static_cast<long double>(J2000));
338 ra = ScopeTarget->ra();
339 de = ScopeTarget->dec();
340 }
341 else
342 {
343 ra = ScopeTarget->ra0();
344 de = ScopeTarget->dec0();
345 }
346 }
347 else
348 {
349 ra = ScopeTarget->ra();
350 de = ScopeTarget->dec();
351 }
352
353 RAEle->value = ra.Hours();
354 DecEle->value = de.Degrees();
355 clientManager->sendNewNumber(EqProp);
356
357 RAEle->value = currentRA;
358 DecEle->value = currentDEC;
359 }
360 // Only send Horizontal Coord property if Equatorial is not available.
361 else if (HorProp)
362 {
363 AzEle->value = ScopeTarget->az().Degrees();
364 AltEle->value = ScopeTarget->alt().Degrees();
365 clientManager->sendNewNumber(HorProp);
366 AzEle->value = currentAz;
367 AltEle->value = currentAlt;
368 }
369
370 return true;
371}
372
373bool TelescopeLite::slew(double ra, double dec)
374{
375 SkyPoint target;
376
377 target.setRA(ra);
378 target.setDec(dec);
379
380 return slew(&target);
381}
382
383bool TelescopeLite::slew(SkyPoint *ScopeTarget)
384{
385 auto motionSP = baseDevice->getSwitch("ON_COORD_SET");
386
387 if (!motionSP)
388 return false;
389
390 auto slewSW = motionSP->findWidgetByName("TRACK");
391
392 if (!slewSW)
393 slewSW = motionSP->findWidgetByName("SLEW");
394
395 if (!slewSW)
396 return false;
397
398 if (slewSW->setState() != ISS_ON)
399 {
400 motionSP->reset();
401 slewSW->setState(ISS_ON);
402 clientManager->sendNewSwitch(motionSP);
403
404 if (Options::iNDILogging())
405 qDebug() << "ISD:Telescope: " << slewSW->getName();
406 }
407
408 return sendCoords(ScopeTarget);
409}
410
411bool TelescopeLite::sync(double ra, double dec)
412{
413 SkyPoint target;
414
415 target.setRA(ra);
416 target.setDec(dec);
417
418 return sync(&target);
419}
420
421bool TelescopeLite::sync(SkyPoint *ScopeTarget)
422{
423 auto motionSP = baseDevice->getSwitch("ON_COORD_SET");
424
425 if (!motionSP)
426 return false;
427
428 auto syncSW = motionSP->findWidgetByName("SYNC");
429
430 if (!syncSW)
431 return false;
432
433 if (syncSW->getState() != ISS_ON)
434 {
435 motionSP->reset();
436 syncSW->setState(ISS_ON);
437 clientManager->sendNewSwitch(motionSP);
438
439 if (Options::iNDILogging())
440 qDebug() << "ISD:Telescope: Syncing...";
441 }
442
443 return sendCoords(ScopeTarget);
444}
445
446bool TelescopeLite::abort()
447{
448 auto motionSP = baseDevice->getSwitch("TELESCOPE_ABORT_MOTION");
449
450 if (!motionSP)
451 return false;
452
453 auto abortSW = motionSP->findWidgetByName("ABORT");
454
455 if (!abortSW)
456 return false;
457
458 if (Options::iNDILogging())
459 qDebug() << "ISD:Telescope: Aborted." << endl;
460
461 abortSW->setState(ISS_ON);
462 clientManager->sendNewSwitch(motionSP);
463
464 return true;
465}
466
467bool TelescopeLite::park()
468{
469 auto parkSP = baseDevice->getSwitch("TELESCOPE_PARK");
470
471 if (!parkSP)
472 return false;
473
474 auto parkSW = parkSP->findWidgetByName("PARK");
475
476 if (!parkSW)
477 return false;
478
479 if (Options::iNDILogging())
480 qDebug() << "ISD:Telescope: Parking..." << endl;
481
482 parkSP->reset();
483 parkSW->setState(ISS_ON);
484 clientManager->sendNewSwitch(parkSP);
485
486 return true;
487}
488
489bool TelescopeLite::unPark()
490{
491 auto parkSP = baseDevice->getSwitch("TELESCOPE_PARK");
492
493 if (!parkSP)
494 return false;
495
496 auto parkSW = parkSP->findWidgetByName("UNPARK");
497
498 if (!parkSW)
499 return false;
500
501 if (Options::iNDILogging())
502 qDebug() << "ISD:Telescope: UnParking..." << endl;
503
504 parkSP->reset();
505 parkSW->setState(ISS_ON);
506 clientManager->sendNewSwitch(parkSP);
507
508 return true;
509}
510
511bool TelescopeLite::getEqCoords(double *ra, double *dec)
512{
513 auto EqProp = baseDevice->getNumber("EQUATORIAL_EOD_COORD");
514
515 if (!EqProp)
516 return false;
517
518 auto RAEle = EqProp->findWidgetByName("RA");
519 if (!RAEle)
520 return false;
521
522 auto DecEle = EqProp->findWidgetByName("DEC");
523 if (!DecEle)
524 return false;
525
526 *ra = RAEle->getValue();
527 *dec = DecEle->getValue();
528
529 return true;
530}
531
532bool TelescopeLite::moveNS(TelescopeMotionNS dir, TelescopeMotionCommand cmd)
533{
534 auto motionSP = baseDevice->getSwitch("TELESCOPE_MOTION_NS");
535
536 if (!motionSP)
537 return false;
538
539 auto motionNorth = motionSP->findWidgetByName("MOTION_NORTH");
540 auto motionSouth = motionSP->findWidgetByName("MOTION_SOUTH");
541
542 if (!motionNorth || !motionSouth)
543 return false;
544
545 // If same direction, return
546 if (dir == MOTION_NORTH && motionNorth->getState() == ((cmd == MOTION_START) ? ISS_ON : ISS_OFF))
547 return true;
548
549 if (dir == MOTION_SOUTH && motionSouth->getState() == ((cmd == MOTION_START) ? ISS_ON : ISS_OFF))
550 return true;
551
552 motionSP->reset();
553
554 if (cmd == MOTION_START)
555 {
556 if (dir == MOTION_NORTH)
557 motionNorth->setState(ISS_ON);
558 else
559 motionSouth->setState(ISS_ON);
560 }
561
562 if (cmd == MOTION_STOP)
563 {
564 if (dir == MOTION_NORTH)
565 motionNorth->setState(ISS_OFF);
566 else
567 motionSouth->setState(ISS_OFF);
568 }
569
570 clientManager->sendNewSwitch(motionSP);
571
572 return true;
573}
574
575bool TelescopeLite::moveWE(TelescopeMotionWE dir, TelescopeMotionCommand cmd)
576{
577 auto motionSP = baseDevice->getSwitch("TELESCOPE_MOTION_WE");
578
579 if (motionSP == nullptr)
580 return false;
581
582 auto motionWest = motionSP->findWidgetByName("MOTION_WEST");
583 auto motionEast = motionSP->findWidgetByName("MOTION_EAST");
584
585 if (motionWest == nullptr || motionEast == nullptr)
586 return false;
587
588 // If same direction, return
589 if (dir == MOTION_WEST && motionWest->getState() == ((cmd == MOTION_START) ? ISS_ON : ISS_OFF))
590 return true;
591
592 if (dir == MOTION_EAST && motionEast->getState() == ((cmd == MOTION_START) ? ISS_ON : ISS_OFF))
593 return true;
594
595 IUResetSwitch(motionSP);
596
597 if (cmd == MOTION_START)
598 {
599 if (dir == MOTION_WEST)
600 motionWest->setState(ISS_ON);
601 else
602 motionEast->setState(ISS_ON);
603 }
604
605 if (cmd == MOTION_STOP)
606 {
607 if (dir == MOTION_WEST)
608 motionWest->setState(ISS_OFF);
609 else
610 motionEast->setState(ISS_OFF);
611 }
612
613 clientManager->sendNewSwitch(motionSP);
614
615 return true;
616}
617
618bool TelescopeLite::setSlewRate(int index)
619{
620 auto slewRateSP = baseDevice->getSwitch("TELESCOPE_SLEW_RATE");
621
622 if (slewRateSP == nullptr)
623 return false;
624
625 int maxSlewRate = slewRateSP->count();
626
627 if (index < 0)
628 {
629 index = 0;
630 }
631 else if (index >= maxSlewRate)
632 {
633 index = maxSlewRate - 1;
634 }
635
636 if (slewRateSP->at(index)->getState() != ISS_ON || index != slewRateIndex)
637 {
638 slewRateSP->reset();
639
640 slewRateSP->at(index)->setState(ISS_ON);
641
642 slewRateIndex = index;
643 setSlewRateLabel(slewRateSP->at(index)->getLabel());
644 setSlewDecreasable(index != 0);
645 setSlewIncreasable(index != maxSlewRate - 1);
646
647 clientManager->sendNewSwitch(slewRateSP);
648 }
649
650 return true;
651}
652
653bool TelescopeLite::decreaseSlewRate()
654{
655 return setSlewRate(slewRateIndex - 1);
656}
657
658bool TelescopeLite::increaseSlewRate()
659{
660 return setSlewRate(slewRateIndex + 1);
661}
662
663void TelescopeLite::setAltLimits(double minAltitude, double maxAltitude)
664{
665 minAlt = minAltitude;
666 maxAlt = maxAltitude;
667}
668
669bool TelescopeLite::isParked()
670{
671 return IsParked;
672}
This class loads QML files and connects SkyMapLite and KStarsData Unlike KStars class it is not a mai...
Definition kstarslite.h:47
static KStarsLite * Instance()
Definition kstarslite.h:77
The sky coordinates of a point in the sky.
Definition skypoint.h:45
void apparentCoord(long double jd0, long double jdf)
Computes the apparent coordinates for this SkyPoint for any epoch, accounting for the effects of prec...
Definition skypoint.cpp:700
const CachingDms & dec() const
Definition skypoint.h:269
const CachingDms & ra0() const
Definition skypoint.h:251
void setDec(dms d)
Sets Dec, the current Declination.
Definition skypoint.h:169
void setRA(dms &r)
Sets RA, the current Right Ascension.
Definition skypoint.h:144
const CachingDms & ra() const
Definition skypoint.h:263
dms altRefracted() const
void EquatorialToHorizontal(const CachingDms *LST, const CachingDms *lat)
Determine the (Altitude, Azimuth) coordinates of the SkyPoint from its (RA, Dec) coordinates,...
Definition skypoint.cpp:77
void setRA0(dms r)
Sets RA0, the catalog Right Ascension.
Definition skypoint.h:94
const dms & az() const
Definition skypoint.h:275
void setAlt(dms alt)
Sets Alt, the Altitude.
Definition skypoint.h:194
const dms & alt() const
Definition skypoint.h:281
void HorizontalToEquatorial(const dms *LST, const dms *lat)
Determine the (RA, Dec) coordinates of the SkyPoint from its (Altitude, Azimuth) coordinates,...
Definition skypoint.cpp:143
void setAz(dms az)
Sets Az, the Azimuth.
Definition skypoint.h:230
const CachingDms & dec0() const
Definition skypoint.h:257
void setDec0(dms d)
Sets Dec0, the catalog Declination.
Definition skypoint.h:119
An angle, stored as degrees, but expressible in many ways.
Definition dms.h:38
double Hours() const
Definition dms.h:168
const double & Degrees() const
Definition dms.h:141
GeoCoordinates geo(const QVariant &location)
void clear()
void push_back(parameter_type value)
qsizetype size() const const
QTextStream & dec(QTextStream &stream)
QTextStream & endl(QTextStream &stream)
void reset()
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 4 2024 16:38:43 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.