Instrument Neutral Distributed Interface INDI  1.9.5
scopesim_helper.h
Go to the documentation of this file.
1 /*
2  * scopesim_helper.h
3  *
4  * Copyright 2020 Chris Rowland <chris.rowland@cherryfield.me.uk>
5  *
6  * helper classes for the telescope simulator
7  *
8  * The Angle structure defines an angle class that manages the wrap round
9  * 0 to 360 and handles arithmetic and logic across this boundary.
10  *
11  * The Axis class manages a simulated mount axis and handles moving, tracking, and guiding.
12  *
13  * The Alignment class handles the alignment, converting between the observed and instrument
14  * places, and allowing for the axis positions needed for a GEM mount.
15  *
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation; either version 2 of the License, or
19  * (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
29  * MA 02110-1301, USA.
30  *
31  *
32  */
33 
34 #pragma once
35 
36 #include <stdint.h>
37 #include <sys/time.h>
38 #include <cmath>
39 
40 #include <indicom.h>
41 
42 static char device_str[64] = "Telescope Simulator";
43 
50 class Angle
51 {
52 private:
53  double angle; // position in degrees, range -180 to 0 to 180
54 
60  static double range(double deg)
61  {
62  while (deg > 180.0) deg -= 360.0;
63  while (deg <= -180.0) deg += 360.0;
64  return deg;
65  }
66 
67  static double hrstoDeg(double hrs) { return range(hrs * 15.0); }
68 
69 public:
71 
72  Angle() { angle = 0; }
73 
74  Angle(double value, ANGLE_UNITS type);
75 
76  Angle(double degrees) { angle = range(degrees); }
77 
78  //virtual ~Angle() = default;
79 
84  double Degrees() {return angle; }
85 
90  double Degrees360()
91  {
92  return (angle >= 0) ? angle : 360.0 + angle;
93  }
94 
99  double Hours()
100  {
101  double h = angle / 15.0;
102  if (h < 0.0)
103  h = 24 + h;
104  return h;
105  }
110  double HoursHa() {return angle / 15.0; }
111 
116  double radians();
117 
123  void setDegrees(double deg) { angle = range(deg); }
124 
129  void setHours(double hrs)
130  {
131  angle = hrstoDeg(hrs);
132  }
133 
135  {
136  double total = a.Degrees() + this->Degrees();
137  return Angle(total);
138  }
139 
141  {
142  return Angle(this->Degrees() - a.Degrees());
143  }
144 
145  double difference(Angle a)
146  {
147  return range(this->angle - a.angle);
148  }
149 
151  {
152  return Angle(-this->angle);
153  }
154 
156  {
157  angle = range(angle + a.angle);
158  return *this;
159  }
160 
161  Angle& operator += (const double d)
162  {
163  angle = range(angle + d);
164  return *this;
165  }
166 
168  {
169  angle = range(angle - a.angle);
170  return *this;
171  }
172 
173  Angle& operator-= (const double d)
174  {
175  angle = range(angle - d);
176  return *this;
177  }
178 
180  {
181  return Angle(this->angle + a.angle);
182  }
183 
184  Angle operator+ (const double& d)
185  {
186  return Angle(this->angle + d);
187  }
188 
189  Angle operator- (const Angle& rhs)
190  {
191  return Angle(this->angle - rhs.angle);
192  }
193 
194  Angle operator- (const double& rhs)
195  {
196  return Angle(this->angle - rhs);
197  }
198 
206  Angle operator * (const double duration)
207  {
208  return Angle(this->angle * duration);
209  }
210 
211  bool operator== (const Angle& a);
212 
213  bool operator!= (const Angle& a);
214 
215  bool operator > (const Angle& a)
216  {
217  return difference(a) > 0;
218  }
219 
220  bool operator < (const Angle& a)
221  {
222  return difference(a) < 0;
223  }
224  bool operator >= (const Angle& a)
225  {
226  return difference(a) >= 0;
227  }
228  bool operator <= (const Angle& a)
229  {
230  return difference(a) <= 0;
231  }
232 };
233 
235 
243 class Axis
244 {
245 public:
250 
251  Axis(const char * name) { axisName = name; }
252 
253  const char * axisName;
254 
255  // sets position and target so does not cause a slew.
256  void setDegrees(double degrees);
257  void setHours(double hours);
258 
259  Angle position; // current axis position
260 
261  void StartSlew(Angle angle);
262 
263  void Abort() { target = position; mcRate = 0; guideDuration = 0; }
264 
265  bool isSlewing;
266 
267  bool isTracking() { return tracking; }
268 
269  void Tracking(bool enabled);
270 
277  void TrackRate(AXIS_TRACK_RATE rate);
278 
284 
289 
295  void StartGuide(double rate, uint32_t durationMs);
296 
297  bool IsGuiding() { return guideDuration > 0; }
298 
299  int mcRate; // int -4 to 4 sets move rate, zero is stopped
300 
301  void update(); // called about once a second to update the position and mode
302 
303  // needed for debug MACROS
304  const char *getDeviceName() { return device_str; }
305 
306 private:
307  Angle target; // target axis position
308 
309  struct timeval lastTime { 0, 0 };
310 
311  bool tracking; // this allows the tracking state and rate to be set independently
312 
313  AXIS_TRACK_RATE trackingRate { AXIS_TRACK_RATE::OFF };
314 
315  Angle rotateCentre { 90.0 };
316 
317  double guideDuration;
318  Angle guideRateDegSec;
319 
320  // rates are angles in degrees per second derived from the values in indicom.h
321  // which are in arcsec per second.
322 
323  const Angle solarRate { TRACKRATE_SOLAR / 3600.0 };
324  const Angle siderealRate { TRACKRATE_SIDEREAL / 3600.0 };
325  const Angle lunarRate { TRACKRATE_LUNAR / 3600.0 };
326 
327  Angle mcRates[5]
328  {
329  0,
330  siderealRate, // guide rate
331  0.5, // fine rate
332  2.5, // center rate
333  6.0, // goto rate
334  };
335 };
336 
365 {
366 public:
368 
370 
373 
375 
383  void mountToApparentRaDec(Angle primary, Angle secondary, Angle * apparentRa, Angle* apparentDec);
384 
385 
386  void apparentRaDecToMount(Angle apparentRa, Angle apparentDec, Angle *primary, Angle *secondary);
387 
388 
398  void setCorrections(double ih, double id, double ch, double np, double ma, double me);
399 
400  void setFlipHourAngle(double deg) { flipHourAngle = deg; }
401 
402  // needed for debug MACROS
403  const char *getDeviceName() { return device_str;}
404 
405  double ih() {return IH;}
406  double id() {return ID;}
407  double np() {return NP;}
408  double ch() {return CH;}
409  double ma() {return MA;}
410  double me() {return ME;}
411 
412  void instrumentToObserved(Angle instrumentHa, Angle instrumentDec, Angle *observedHa, Angle *observedDec);
413 
414  void observedToInstrument(Angle observedHa, Angle observedDec, Angle * instrumentHa, Angle * instrumentDec);
415 
416 
424  void mountToApparentHaDec(Angle primary, Angle secondary, Angle *apparentHa, Angle *apparentDec);
425 
433  void apparentHaDecToMount(Angle apparentHa, Angle apparentDec, Angle *primary, Angle *secondary);
434 
435  Angle lst(); // returns the current LST as an angle
436 private:
437 
438 
439 
440 
441  Angle flipHourAngle = 0;
442 
460  void correction(Angle instrumentHa, Angle instrumentDec, Angle *correctionHa, Angle *correctionDec);
461 
462  // mount model, these angles are in degrees
463  // the angles are small so use double to avoid
464  // loads of conversions
468  double IH = 0;
472  double ID = 0;
476  double CH = 0;
480  double NP = 0;
484  double MA = 0;
488  double ME = 0;
489 
490 
491  // corrections done using direction cosines and rotations after Taki
492  //apparentHaDecToMount(Vector HaDec, Vector * mount);
493 };
494 
503 class Vector
504 {
505 public:
510  Vector() { L = M = N = 0; }
511 
518  Vector(double l, double m, double n);
519 
526 
527  double lengthSquared() { return L * L + M * M + N * N; }
528 
529  double length() { return std::sqrt(lengthSquared()); }
530 
531  void normalise();
532 
537  Angle primary();
538 
543  Angle secondary();
544 
549  Vector rotateX(Angle angle);
550 
555  Vector rotateY(Angle angle);
556 
561  Vector rotateZ(Angle angle);
562 
563  double l() { return L; }
564  double m() { return M; }
565  double n() { return N; }
566 
567 protected:
568  double L; // in the Ha 0 direction, pointing at Ha 0, Dec 0, X direction
569  double M; // in the Ha 6 direction, pointing at Ha 6h, Dec 0, Y direction
570  double N; // toward the pole, Dec 0, Z direction
571 };
Angle::operator+=
Angle & operator+=(const Angle &a)
Definition: scopesim_helper.h:155
Axis
The Axis class Implements a generic Axis which can be used for equatorial or AltAz mounts for both ax...
Definition: scopesim_helper.h:243
Alignment::instrumentToObserved
void instrumentToObserved(Angle instrumentHa, Angle instrumentDec, Angle *observedHa, Angle *observedDec)
Definition: scopesim_helper.cpp:321
Alignment::mountToApparentHaDec
void mountToApparentHaDec(Angle primary, Angle secondary, Angle *apparentHa, Angle *apparentDec)
mountToApparentHaDec: convert mount position to apparent Ha, Dec
Definition: scopesim_helper.cpp:226
Angle::DEGREES
@ DEGREES
Definition: scopesim_helper.h:70
Alignment::longitude
Angle longitude
Definition: scopesim_helper.h:372
Axis::getDeviceName
const char * getDeviceName()
Definition: scopesim_helper.h:304
Angle::operator-
Angle operator-()
Definition: scopesim_helper.h:150
Angle::Angle
Angle()
Definition: scopesim_helper.h:72
Axis::LUNAR
@ LUNAR
Definition: scopesim_helper.h:249
Alignment::apparentRaDecToMount
void apparentRaDecToMount(Angle apparentRa, Angle apparentDec, Angle *primary, Angle *secondary)
Definition: scopesim_helper.cpp:312
Vector::Vector
Vector()
Vector creates an empty vector.
Definition: scopesim_helper.h:510
Vector::rotateZ
Vector rotateZ(Angle angle)
rotateZ rotates this vector through angle about the Z axis
Definition: scopesim_helper.cpp:536
Vector::length
double length()
Definition: scopesim_helper.h:529
Alignment::id
double id()
Definition: scopesim_helper.h:406
indicom.h
Implementations for common driver routines.
Alignment::MOUNT_TYPE
MOUNT_TYPE
Definition: scopesim_helper.h:369
Alignment::apparentHaDecToMount
void apparentHaDecToMount(Angle apparentHa, Angle apparentDec, Angle *primary, Angle *secondary)
apparentHaDecToMount
Definition: scopesim_helper.cpp:269
Alignment::np
double np()
Definition: scopesim_helper.h:407
Axis::Abort
void Abort()
Definition: scopesim_helper.h:263
Angle::radians
double radians()
radians
Definition: scopesim_helper.cpp:48
Axis::TrackingRateDegSec
Angle TrackingRateDegSec
TrackingRateDegSec.
Definition: scopesim_helper.h:288
Vector::m
double m()
Definition: scopesim_helper.h:564
Axis::isTracking
bool isTracking()
Definition: scopesim_helper.h:267
Vector::rotateY
Vector rotateY(Angle angle)
rotateY rotates this vector through angle about the Y axis
Definition: scopesim_helper.cpp:529
Alignment::mountToApparentRaDec
void mountToApparentRaDec(Angle primary, Angle secondary, Angle *apparentRa, Angle *apparentDec)
mountToApparentRaDec: convert mount position to apparent Ra, Dec
Definition: scopesim_helper.cpp:261
Angle::subtract
Angle subtract(Angle a)
Definition: scopesim_helper.h:140
Axis::OFF
@ OFF
Definition: scopesim_helper.h:249
Angle::operator-=
Angle & operator-=(const Angle &a)
Definition: scopesim_helper.h:167
Axis::update
void update()
Definition: scopesim_helper.cpp:124
Angle::HOURS
@ HOURS
Definition: scopesim_helper.h:70
Axis::AXIS_TRACK_RATE
AXIS_TRACK_RATE
The AXIS_TRACK_RATE enum defines the common track rates.
Definition: scopesim_helper.h:249
Angle::operator==
bool operator==(const Angle &a)
Definition: scopesim_helper.cpp:50
Axis::IsGuiding
bool IsGuiding()
Definition: scopesim_helper.h:297
Vector::n
double n()
Definition: scopesim_helper.h:565
Angle
The Angle class This class implements an angle type. This holds an angle that is always in the range ...
Definition: scopesim_helper.h:50
Alignment::mountType
MOUNT_TYPE mountType
Definition: scopesim_helper.h:374
Angle::Angle
Angle(double degrees)
Definition: scopesim_helper.h:76
Vector::L
double L
Definition: scopesim_helper.h:568
Alignment::ch
double ch()
Definition: scopesim_helper.h:408
Angle::HoursHa
double HoursHa()
HoursHa.
Definition: scopesim_helper.h:110
Alignment::setFlipHourAngle
void setFlipHourAngle(double deg)
Definition: scopesim_helper.h:400
type
__le16 type
Definition: pwc-ioctl.h:2
Vector::normalise
void normalise()
Definition: scopesim_helper.cpp:500
Alignment::setCorrections
void setCorrections(double ih, double id, double ch, double np, double ma, double me)
setCorrections set the values of the six corrections
Definition: scopesim_helper.cpp:465
Angle::Degrees
double Degrees()
Degrees.
Definition: scopesim_helper.h:84
Axis::StartGuide
void StartGuide(double rate, uint32_t durationMs)
StartGuide start guiding.
Definition: scopesim_helper.cpp:115
Alignment::ma
double ma()
Definition: scopesim_helper.h:409
Vector::N
double N
Definition: scopesim_helper.h:570
Angle::operator+
Angle operator+(const Angle &a)
Definition: scopesim_helper.h:179
Axis::setDegrees
void setDegrees(double degrees)
Definition: scopesim_helper.cpp:64
Vector::rotateX
Vector rotateX(Angle angle)
rotateX rotates this vector through angle about the X axis
Definition: scopesim_helper.cpp:522
Axis::TrackRate
AXIS_TRACK_RATE TrackRate()
TrackRate returns the AXIS_TRACK_RATE property.
Definition: scopesim_helper.cpp:110
Alignment::ALTAZ
@ ALTAZ
Definition: scopesim_helper.h:369
Axis::Axis
Axis(const char *name)
Definition: scopesim_helper.h:251
Vector::primary
Angle primary()
primary returns the primary angle (Ra, Ha, Azimuth) from this vector
Definition: scopesim_helper.cpp:508
TRACKRATE_LUNAR
#define TRACKRATE_LUNAR
Definition: indicom.h:57
Angle::add
Angle add(Angle a)
Definition: scopesim_helper.h:134
Angle::ANGLE_UNITS
ANGLE_UNITS
Definition: scopesim_helper.h:70
Angle::RADIANS
@ RADIANS
Definition: scopesim_helper.h:70
Vector::M
double M
Definition: scopesim_helper.h:569
Axis::isSlewing
bool isSlewing
Definition: scopesim_helper.h:265
Angle::operator>
bool operator>(const Angle &a)
Definition: scopesim_helper.h:215
TRACKRATE_SOLAR
#define TRACKRATE_SOLAR
Definition: indicom.h:56
name
const char * name
Definition: indiserver.c:116
Vector::secondary
Angle secondary()
secondary returns the secondary angle (dec, altitude) from this vector
Definition: scopesim_helper.cpp:515
Axis::Tracking
void Tracking(bool enabled)
Definition: scopesim_helper.cpp:83
Alignment::lst
Angle lst()
Definition: scopesim_helper.cpp:221
Axis::SOLAR
@ SOLAR
Definition: scopesim_helper.h:249
Angle::operator<=
bool operator<=(const Angle &a)
Definition: scopesim_helper.h:228
Axis::axisName
const char * axisName
Definition: scopesim_helper.h:253
Axis::StartSlew
void StartSlew(Angle angle)
Definition: scopesim_helper.cpp:76
Alignment::EQ_FORK
@ EQ_FORK
Definition: scopesim_helper.h:369
Angle::operator!=
bool operator!=(const Angle &a)
Definition: scopesim_helper.cpp:55
Angle::Hours
double Hours()
Hours.
Definition: scopesim_helper.h:99
TRACKRATE_SIDEREAL
#define TRACKRATE_SIDEREAL
Definition: indicom.h:54
Alignment::getDeviceName
const char * getDeviceName()
Definition: scopesim_helper.h:403
Alignment::me
double me()
Definition: scopesim_helper.h:410
Angle::operator>=
bool operator>=(const Angle &a)
Definition: scopesim_helper.h:224
Angle::Degrees360
double Degrees360()
Degrees360.
Definition: scopesim_helper.h:90
Axis::setHours
void setHours(double hours)
Definition: scopesim_helper.cpp:70
Angle::setDegrees
void setDegrees(double deg)
setDegrees set the angle in degrees
Definition: scopesim_helper.h:123
OFF
#define OFF
Definition: stvdriver.h:26
Vector
The Vector class This implements the Directional Cosine used by Taki in his Matrix method....
Definition: scopesim_helper.h:503
Alignment::Alignment
Alignment()
Definition: scopesim_helper.h:367
Angle::operator<
bool operator<(const Angle &a)
Definition: scopesim_helper.h:220
Alignment::ih
double ih()
Definition: scopesim_helper.h:405
Angle::setHours
void setHours(double hrs)
setHours set the angle
Definition: scopesim_helper.h:129
Alignment
The Alignment class This converts between the mount axis angles and the sky hour angle and declinatio...
Definition: scopesim_helper.h:364
Axis::position
Angle position
Definition: scopesim_helper.h:259
Alignment::observedToInstrument
void observedToInstrument(Angle observedHa, Angle observedDec, Angle *instrumentHa, Angle *instrumentDec)
Definition: scopesim_helper.cpp:349
Vector::l
double l()
Definition: scopesim_helper.h:563
Alignment::EQ_GEM
@ EQ_GEM
Definition: scopesim_helper.h:369
Angle::operator*
Angle operator*(const double duration)
operator * multiplies the angle by a double, used to manage tracking and slewing
Definition: scopesim_helper.h:206
Angle::difference
double difference(Angle a)
Definition: scopesim_helper.h:145
Axis::SIDEREAL
@ SIDEREAL
Definition: scopesim_helper.h:249
Axis::mcRate
int mcRate
Definition: scopesim_helper.h:299
Vector::lengthSquared
double lengthSquared()
Definition: scopesim_helper.h:527
Alignment::latitude
Angle latitude
Definition: scopesim_helper.h:371