Instrument Neutral Distributed Interface INDI  2.0.2
test_eq500xdriver.cpp
Go to the documentation of this file.
1 #include <stdarg.h>
2 #include <cmath>
3 #include <memory>
4 #include <cstring>
5 #include <termios.h>
6 #include <unistd.h>
7 #include <cassert>
8 
9 #include <libnova/sidereal_time.h>
10 #include <libnova/transform.h>
11 
12 #include "lx200generic.h"
13 #include "eq500x.h"
14 
15 #include "indicom.h"
16 #include "indilogger.h"
17 #include "lx200driver.h"
18 
19 #include <gtest/gtest.h>
20 #include <gmock/gmock.h>
21 
22 using ::testing::_;
23 using ::testing::StrEq;
24 
25 char _me[] = "MockEQ500XDriver";
26 char *me = _me;
27 class MockEQ500XDriver : public EQ500X
28 {
29  public:
31  {
33  ISGetProperties("");
34  setSimulation(true);
35  //setDebug(true);
36  //char * names[] = {"DBG_DEBUG"};
37  //ISState states[] = {ISS_ON};
38  //ISNewSwitch(getDeviceName(),"DEBUG_LEVEL",states,names,1);
39  if (checkConnection())
40  setConnected(true);
41  }
42  public:
43  // Default LST for this driver is 6 - RA is east when starting up
44  double LST { 6 };
45  double getLST()
46  {
47  return LST;
48  }
50  {
52  }
54  {
55  return TrackState;
56  }
58  {
59  return getCurrentPollingPeriod();
60  }
61  int getSlewRateIndex() const
62  {
64  }
65  public:
66  void setLongitude(double lng)
67  {
68  /* Say it's 0h on Greenwich meridian (GHA=0) - express LST as hours */
69  LST = 0.0 + lng / 15.0;
70  updateLocation(0, lng, 0);
71  }
73  {
74  return ReadScopeStatus();
75  }
76  bool executeGotoOffset(double ra_offset, double dec_offset)
77  {
78  return Goto(std::fmod(currentRA + ra_offset, 24.0), currentDEC + dec_offset);
79  }
80  bool executeAbort()
81  {
82  return Abort();
83  }
84  bool executeSync(double ra, double dec)
85  {
86  return Sync(ra, dec);
87  }
88 };
89 
90 
91 // Right ascension is normal sexagesimal mapping.
92 //
93 // HA = LST - RA
94 //
95 // South is HA = +0, RA = LST
96 // East is HA = -6, RA = LST+6
97 // North is HA = -12, RA = LST+12 on the east side
98 // West is HA = +6, RA = LST-6
99 // North is HA = +12, RA = LST-12 on the west side
100 //
101 // Telescope on western side of pier is 12 hours later than
102 // telescope on eastern side of pier.
103 //
104 // PierEast (LST = -6) PierWest
105 // E +12.0h = LST-18 <-> 12:00:00 <-> LST-18 = +00.0h W
106 // N +18.0h = LST-12 <-> 18:00:00 <-> LST-12 = +06.0h N
107 // W +00.0h = LST-6 <-> 00:00:00 <-> LST-6 = +12.0h E
108 // S +06.0h = LST+0 <-> 06:00:00 <-> LST+0 = +18.0h S
109 // E +12.0h = LST+6 <-> 12:00:00 <-> LST+6 = +00.0h W
110 // N +18.0h = LST+12 <-> 18:00:00 <-> LST+12 = +06.0h N
111 // W +00.0h = LST+18 <-> 00:00:00 <-> LST+18 = +12.0h E
112 
113 TEST(EQ500XDriverTest, test_LSTSync)
114 {
116 
117  ASSERT_TRUE(d.isConnected());
118 
120  // Assign a longitude that makes the RA of the scope point east - default position is 90° east
121  d.setLongitude(6 * 15);
122  ASSERT_FALSE(d.getCurrentMechanicalPosition(p));
123  ASSERT_DOUBLE_EQ( +0.0, p.RAsky());
124  ASSERT_DOUBLE_EQ( +90.0, p.DECsky());
125  // Assign a new longitude
126  d.setLongitude(5 * 15);
127  ASSERT_FALSE(d.getCurrentMechanicalPosition(p));
128  ASSERT_DOUBLE_EQ( 23.0, p.RAsky());
129  ASSERT_DOUBLE_EQ( +90.0, p.DECsky());
130  // Assign a new longitude - but this time the mount is not considered "parked" east/pole and does not sync
131  d.setLongitude(7 * 15);
132  ASSERT_FALSE(d.getCurrentMechanicalPosition(p));
133  ASSERT_DOUBLE_EQ( 23.0, p.RAsky()); // Expected 1h - not possible to assign longitude without restarting the mount
134  ASSERT_DOUBLE_EQ( +90.0, p.DECsky());
135 }
136 
137 TEST(EQ500XDriverTest, test_MechanicalPoint_Equality)
138 {
140 
141  p.RAm(1.23456789);
142  p.DECm(1.23456789);
144  q.RAm(1.23456789);
145  q.DECm(1.23456789);
147  ASSERT_TRUE(p == q);
148  ASSERT_FALSE(p != q);
150  ASSERT_FALSE(p == q);
151  ASSERT_TRUE(p != q);
153  q.RAm(q.RAm() + 15.0 / 3600.0);
154  ASSERT_FALSE(p == q);
155  ASSERT_TRUE(p != q);
156  q.RAm(q.RAm() - 15.0 / 3600.0);
157  ASSERT_TRUE(p == q);
158  ASSERT_FALSE(p != q);
159  q.DECm(q.DECm() + 1.0 / 3600.0);
160  ASSERT_FALSE(p == q);
161  ASSERT_TRUE(p != q);
162  q.DECm(q.DECm() - 1.0 / 3600.0);
163  ASSERT_TRUE(p == q);
164  ASSERT_FALSE(p != q);
165 }
166 
167 TEST(EQ500XDriverTest, test_MechanicalPoint_RA_distance)
168 {
170 
171  ASSERT_EQ( 0.0, p.RAsky(0.0));
172  ASSERT_EQ( 1.0, q.RAsky(1.0));
173  ASSERT_EQ( 1.0 * 15, p.RA_degrees_to(q));
174  ASSERT_EQ( -1.0 * 15, q.RA_degrees_to(p));
175 
176  ASSERT_EQ( 2.0, q.RAsky(2.0));
177  ASSERT_EQ( 2.0 * 15, p.RA_degrees_to(q));
178  ASSERT_EQ( -2.0 * 15, q.RA_degrees_to(p));
179 
180  ASSERT_EQ( 8.0, q.RAsky(8.0));
181  ASSERT_EQ( 8.0 * 15, p.RA_degrees_to(q));
182  ASSERT_EQ( -8.0 * 15, q.RA_degrees_to(p));
183 
184  ASSERT_EQ( 12.0, q.RAsky(12.0));
185  ASSERT_EQ( 12.0 * 15, p.RA_degrees_to(q));
186  ASSERT_EQ(-12.0 * 15, q.RA_degrees_to(p));
187 
188  ASSERT_EQ( 18.0, q.RAsky(18.0));
189  ASSERT_EQ( -6.0 * 15, p.RA_degrees_to(q));
190  ASSERT_EQ( +6.0 * 15, q.RA_degrees_to(p));
191 }
192 
193 TEST(EQ500XDriverTest, test_MechanicalPoint_PierFlip)
194 {
196  char b[64] = {0};
197 
198  // Mechanical point doesn't care about LST as it assumes the mount
199  // is properly synced already. It only considers the pointing state.
200 
202  ASSERT_DOUBLE_EQ( 0.0, p.RAsky ( +0.0));
203  ASSERT_DOUBLE_EQ(+90.0, p.DECsky(+90.0));
204  ASSERT_FALSE(strncmp( "12:00:00", p.toStringRA (b, 64), 64));
205  ASSERT_FALSE(strncmp("+00:00:00", p.toStringDEC(b, 64), 64));
207  ASSERT_DOUBLE_EQ( 0.0, p.RAsky ( +0.0));
208  ASSERT_DOUBLE_EQ(+90.0, p.DECsky(+90.0));
209  ASSERT_FALSE(strncmp( "00:00:00", p.toStringRA (b, 64), 64));
210  ASSERT_FALSE(strncmp("+00:00:00", p.toStringDEC(b, 64), 64));
211 
213  ASSERT_DOUBLE_EQ( 0.0, p.RAsky ( +0.0));
214  ASSERT_DOUBLE_EQ(+80.0, p.DECsky(+80.0));
215  ASSERT_FALSE(strncmp( "12:00:00", p.toStringRA (b, 64), 64));
216  ASSERT_FALSE(strncmp("-10:00:00", p.toStringDEC(b, 64), 64));
218  ASSERT_DOUBLE_EQ( 0.0, p.RAsky ( +0.0));
219  ASSERT_DOUBLE_EQ(+80.0, p.DECsky(+80.0));
220  ASSERT_FALSE(strncmp( "00:00:00", p.toStringRA (b, 64), 64));
221  ASSERT_FALSE(strncmp("+10:00:00", p.toStringDEC(b, 64), 64));
222 
224  ASSERT_DOUBLE_EQ( 0.0, p.RAsky ( +0.0));
225  ASSERT_DOUBLE_EQ(+70.0, p.DECsky(+70.0));
226  ASSERT_FALSE(strncmp( "12:00:00", p.toStringRA (b, 64), 64));
227  ASSERT_FALSE(strncmp("-20:00:00", p.toStringDEC(b, 64), 64));
229  ASSERT_DOUBLE_EQ( 0.0, p.RAsky ( +0.0));
230  ASSERT_DOUBLE_EQ(+70.0, p.DECsky(+70.0));
231  ASSERT_FALSE(strncmp( "00:00:00", p.toStringRA (b, 64), 64));
232  ASSERT_FALSE(strncmp("+20:00:00", p.toStringDEC(b, 64), 64));
233 }
234 
235 TEST(EQ500XDriverTest, test_Stability_RA_Conversions)
236 {
238  for (size_t ps = 0; ps < sizeof(sides) / sizeof(sides[0]); ps++)
239  {
240  for (int s = 0; s < 60; s++)
241  {
242  for (int m = 0; m < 60; m++)
243  {
244  for (int h = 0; h < 24; h++)
245  {
246  // Locals are on purpose - reset test material on each loop
248  char b[64] = {0}, c[64] = {0};
249 
250  p.setPointingState(sides[ps]);
251 
252  snprintf(b, sizeof(b), "%02d:%02d:%02d", h, m, s);
253  p.parseStringRA(b, sizeof(b));
254  p.toStringRA(c, sizeof(c));
255 
256  ASSERT_FALSE(strncmp(b, c, sizeof(b)));
257  }
258  }
259  }
260  }
261 }
262 
263 TEST(EQ500XDriverTest, test_Stability_DEC_Conversions)
264 {
265  // Doesn't test outside of -90,+90 but another test does roughly
267  for (size_t ps = 0; ps < sizeof(sides) / sizeof(sides[0]); ps++)
268  {
269  for (int s = 0; s < 60; s++)
270  {
271  for (int m = 0; m < 60; m++)
272  {
273  for (int d = -89; d <= +89; d++)
274  {
275  // Locals are on purpose - reset test material on each loop
277  char b[64] = {0}, c[64] = {0};
278 
279  p.setPointingState(sides[ps]);
280 
281  snprintf(b, sizeof(b), "%+03d:%02d:%02d", d, m, s);
282  p.parseStringDEC(b, sizeof(b));
283  p.toStringDEC(c, sizeof(c));
284 
285  // Debug test with this block
286  if (strncmp(b, c, sizeof(b)))
287  {
288  p.parseStringDEC(b, sizeof(b));
289  p.toStringDEC(c, sizeof(c));
290  }
291 
292  ASSERT_FALSE(strncmp(b, c, sizeof(b)));
293  }
294  }
295  }
296  }
297 }
298 
299 TEST(EQ500XDriverTest, test_NormalPointing_RA_Conversions)
300 {
302  char b[64] = {0};
303 
305 
306  ASSERT_FALSE(p.parseStringRA("00:00:00", 8));
307  ASSERT_DOUBLE_EQ( +0.0, p.RAsky());
308  ASSERT_FALSE(strncmp("00:00:00", p.toStringRA(b, 64), 64));
309 
310  ASSERT_FALSE(p.parseStringRA("06:00:00", 8));
311  ASSERT_DOUBLE_EQ( +6.0, p.RAsky());
312  ASSERT_FALSE(strncmp("06:00:00", p.toStringRA(b, 64), 64));
313 
314  ASSERT_FALSE(p.parseStringRA("12:00:00", 8));
315  ASSERT_DOUBLE_EQ(+12.0, p.RAsky());
316  ASSERT_FALSE(strncmp("12:00:00", p.toStringRA(b, 64), 64));
317 
318  ASSERT_FALSE(p.parseStringRA("18:00:00", 8));
319  ASSERT_DOUBLE_EQ(+18.0, p.RAsky());
320  ASSERT_FALSE(strncmp("18:00:00", p.toStringRA(b, 64), 64));
321 
322  ASSERT_FALSE(p.parseStringRA("24:00:00", 8));
323  ASSERT_DOUBLE_EQ( +0.0, p.RAsky());
324  ASSERT_FALSE(strncmp("00:00:00", p.toStringRA(b, 64), 64));
325 
326  ASSERT_FALSE(p.parseStringRA("00:00:01", 8));
327  ASSERT_NEAR(1 / 3600.0, p.RAsky(), 1 / 3600.0);
328  ASSERT_FALSE(strncmp("00:00:01", p.toStringRA(b, 64), 64));
329 
330  ASSERT_FALSE(p.parseStringRA("00:01:00", 8));
331  ASSERT_NEAR(1 / 60.0, p.RAsky(), 1 / 3600.0);
332  ASSERT_FALSE(strncmp("00:01:00", p.toStringRA(b, 64), 64));
333 }
334 
335 TEST(EQ500XDriverTest, test_BeyondPolePointing_RA_Conversions)
336 {
338  char b[64] = {0};
339 
341 
342  ASSERT_FALSE(p.parseStringRA("00:00:00", 8));
343  ASSERT_EQ(+12.0, p.RAsky());
344  ASSERT_FALSE(strncmp("00:00:00", p.toStringRA(b, 64), 64));
345 
346  ASSERT_FALSE(p.parseStringRA("06:00:00", 8));
347  ASSERT_EQ(+18.0, p.RAsky());
348  ASSERT_FALSE(strncmp("06:00:00", p.toStringRA(b, 64), 64));
349 
350  ASSERT_FALSE(p.parseStringRA("12:00:00", 8));
351  ASSERT_EQ( +0.0, p.RAsky());
352  ASSERT_FALSE(strncmp("12:00:00", p.toStringRA(b, 64), 64));
353 
354  ASSERT_FALSE(p.parseStringRA("18:00:00", 8));
355  ASSERT_EQ( +6.0, p.RAsky());
356  ASSERT_FALSE(strncmp("18:00:00", p.toStringRA(b, 64), 64));
357 
358  ASSERT_FALSE(p.parseStringRA("24:00:00", 8));
359  ASSERT_EQ(+12.0, p.RAsky());
360  ASSERT_FALSE(strncmp("00:00:00", p.toStringRA(b, 64), 64));
361 }
362 
363 // Declination goes from -255:59:59 to +255:59:59
364 //
365 // When reading, tenths and hundredths share the same character:
366 // - 0-9 is mapped to {0,1,2,3,4,5,6,7,8,9}
367 // - 10-16 is mapped to {:,;,<,=,>,?,@}
368 // - 17-25 is mapped to {A,B,C,D,E,F,G,H,I}
369 //
370 // Side of pier is deduced by raw DEC value, which is offset by 90 degrees
371 // - raw DEC in [0,+180] means "normal".
372 // - raw DEC in [-180,0] means "beyond pole".
373 // We support [+270,+256[ (beyond) and ]-256,-270] (normal) for convenience.
374 //
375 // Beyond W Mount DEC R Normal
376 //(-165.0°)<-> -255:00:00 = -255.0 = -I5:00:00 <-> +345.0°
377 //(-135.0°)<-> -225:00:00 = -F5:00:00 <-> +315.0°
378 // -90.0° <-> -180:00:00 = -B0:00:00 <-> +270.0°
379 // -45.0° <-> -135:00:00 = -=5:00:00 <->(+225.0°)
380 // +00.0° <-> -90:00:00 = -90:00:00 <->(+180.0°)
381 // +45.0° <-> -45:00:00 = -45:00:00 <->(+135.0°)
382 // +90.0° <-> 0:00:00 = +00:00:00 <-> +90.0°
383 //(+135.0°)<-> 45:00:00 = +45:00:00 <-> +45.0°
384 //(+180.0°)<-> 90:00:00 = +90:00:00 <-> +00.0°
385 //(+225.0°)<-> 135:00:00 = +=5:00:00 <-> -45.0°
386 // +270.0°)<-> 180:00:00 = +B0:00:00 <-> -90.0°
387 // +315.0° <-> 225:00:00 = +F5:00:00 <->(-135.0°)
388 // +345.0° <-> 255:00:00 = +I5:00:00 <->(-165.0°)
389 
390 TEST(EQ500XDriverTest, test_MechanicalPoint_Sky_DEC_Conversion)
391 {
393 
394  ASSERT_EQ(-255.0, p.DECm(-255.0));
396  ASSERT_EQ( -15.0, p.DECsky());
397  ASSERT_EQ( -15.0, p.DECsky( -15.0));
398  ASSERT_EQ(+105.0, p.DECm());
399 
400  ASSERT_EQ(-225.0, p.DECm(-225.0));
402  ASSERT_EQ( -45.0, p.DECsky());
403  ASSERT_EQ( -45.0, p.DECsky( -45.0));
404  ASSERT_EQ(+135.0, p.DECm());
405 
406  ASSERT_EQ(-180.0, p.DECm(-180.0));
408  ASSERT_EQ( -90.0, p.DECsky());
409  ASSERT_EQ( -90.0, p.DECsky( -90.0));
410  ASSERT_EQ(-180.0, p.DECm());
411 
412  ASSERT_EQ(-135.0, p.DECm(-135.0));
414  ASSERT_EQ( -45.0, p.DECsky());
415  ASSERT_EQ( -45.0, p.DECsky( -45.0));
416  ASSERT_EQ(-135.0, p.DECm());
417 
418  ASSERT_EQ( -90.0, p.DECm( -90.0));
420  ASSERT_EQ( +0.0, p.DECsky());
421  ASSERT_EQ( +0.0, p.DECsky( +0.0));
422  ASSERT_EQ( -90.0, p.DECm());
423 
424  ASSERT_EQ( -45.0, p.DECm( -45.0));
426  ASSERT_EQ( +45.0, p.DECsky());
427  ASSERT_EQ( +45.0, p.DECsky( +45.0));
428  ASSERT_EQ( -45.0, p.DECm());
429 
430  ASSERT_EQ( +0.0, p.DECm( +0.0));
432  ASSERT_EQ( +90.0, p.DECsky());
433  ASSERT_EQ( +90.0, p.DECsky( +90.0));
434  ASSERT_EQ( +0.0, p.DECm());
435 
436  ASSERT_EQ( +45.0, p.DECm( +45.0));
438  ASSERT_EQ( +45.0, p.DECsky());
439  ASSERT_EQ( +45.0, p.DECsky( +45.0));
440  ASSERT_EQ( +45.0, p.DECm());
441 
442  ASSERT_EQ( +90.0, p.DECm( +90.0));
444  ASSERT_EQ( +0.0, p.DECsky());
445  ASSERT_EQ( +0.0, p.DECsky( +0.0));
446  ASSERT_EQ( +90.0, p.DECm());
447 
448  ASSERT_EQ(+135.0, p.DECm(+135.0));
450  ASSERT_EQ( -45.0, p.DECsky());
451  ASSERT_EQ( -45.0, p.DECsky( -45.0));
452  ASSERT_EQ(+135.0, p.DECm());
453 
454  ASSERT_EQ(+180.0, p.DECm(+180.0));
456  ASSERT_EQ( -90.0, p.DECsky());
457  ASSERT_EQ( -90.0, p.DECsky( -90.0));
458  ASSERT_EQ(+180.0, p.DECm());
459 
460  ASSERT_EQ(+225.0, p.DECm(+225.0));
462  ASSERT_EQ( -45.0, p.DECsky());
463  ASSERT_EQ( -45.0, p.DECsky( -45.0));
464  ASSERT_EQ(-135.0, p.DECm());
465 
466  ASSERT_EQ(+255.0, p.DECm(+255.0));
468  ASSERT_EQ( -15.0, p.DECsky());
469  ASSERT_EQ( -15.0, p.DECsky( -15.0));
470  ASSERT_EQ(-105.0, p.DECm());
471 }
472 
473 TEST(EQ500XDriverTest, test_DEC_Conversions)
474 {
476  char b[64] = {0};
477 
478  ASSERT_FALSE(p.parseStringDEC("-I5:00:00", 9));
479  ASSERT_EQ(-255.0, p.DECm());
480  ASSERT_FALSE(strncmp("-I5:00:00", p.toStringDEC_Sim(b, 64), 64));
481  ASSERT_FALSE(strncmp("-255:00:00", p.toStringDEC(b, 64), 64));
483 
484  ASSERT_FALSE(p.parseStringDEC("-F5:00:00", 9));
485  ASSERT_EQ(-225.0, p.DECm());
486  ASSERT_FALSE(strncmp("-F5:00:00", p.toStringDEC_Sim(b, 64), 64));
487  ASSERT_FALSE(strncmp("-225:00:00", p.toStringDEC(b, 64), 64));
489 
490  ASSERT_FALSE(p.parseStringDEC("-B0:00:00", 9));
491  ASSERT_EQ(-180.0, p.DECm());
492  ASSERT_FALSE(strncmp("-B0:00:00", p.toStringDEC_Sim(b, 64), 64));
493  ASSERT_FALSE(strncmp("-180:00:00", p.toStringDEC(b, 64), 64));
495 
496  ASSERT_FALSE(p.parseStringDEC("-=5:00:00", 9));
497  ASSERT_EQ(-135.0, p.DECm());
498  ASSERT_FALSE(strncmp("-=5:00:00", p.toStringDEC_Sim(b, 64), 64));
499  ASSERT_FALSE(strncmp("-135:00:00", p.toStringDEC(b, 64), 64));
501 
502  ASSERT_FALSE(p.parseStringDEC("-90:00:00", 9));
503  ASSERT_EQ( -90.0, p.DECm());
504  ASSERT_FALSE(strncmp("-90:00:00", p.toStringDEC_Sim(b, 64), 64));
505  ASSERT_FALSE(strncmp("-90:00:00", p.toStringDEC(b, 64), 64));
507 
508  ASSERT_FALSE(p.parseStringDEC("-45:00:00", 9));
509  ASSERT_EQ( -45.0, p.DECm());
510  ASSERT_FALSE(strncmp("-45:00:00", p.toStringDEC_Sim(b, 64), 64));
511  ASSERT_FALSE(strncmp("-45:00:00", p.toStringDEC(b, 64), 64));
513 
514  ASSERT_FALSE(p.parseStringDEC("+00:00:00", 9));
515  ASSERT_EQ( +0.0, p.DECm());
516  ASSERT_FALSE(strncmp("+00:00:00", p.toStringDEC_Sim(b, 64), 64));
517  ASSERT_FALSE(strncmp("+00:00:00", p.toStringDEC(b, 64), 64));
519 
520  ASSERT_FALSE(p.parseStringDEC("+45:00:00", 9));
521  ASSERT_EQ( +45.0, p.DECm());
522  ASSERT_FALSE(strncmp("+45:00:00", p.toStringDEC_Sim(b, 64), 64));
523  ASSERT_FALSE(strncmp("+45:00:00", p.toStringDEC(b, 64), 64));
525 
526  ASSERT_FALSE(p.parseStringDEC("+90:00:00", 9));
527  ASSERT_EQ( +90.0, p.DECm());
528  ASSERT_FALSE(strncmp("+90:00:00", p.toStringDEC_Sim(b, 64), 64));
529  ASSERT_FALSE(strncmp("+90:00:00", p.toStringDEC(b, 64), 64));
531 
532  ASSERT_FALSE(p.parseStringDEC("+=5:00:00", 9));
533  ASSERT_EQ(+135.0, p.DECm());
534  ASSERT_FALSE(strncmp("+=5:00:00", p.toStringDEC_Sim(b, 64), 64));
535  ASSERT_FALSE(strncmp("+135:00:00", p.toStringDEC(b, 64), 64));
537 
538  ASSERT_FALSE(p.parseStringDEC("+B0:00:00", 9));
539  ASSERT_EQ(+180.0, p.DECm());
540  ASSERT_FALSE(strncmp("+B0:00:00", p.toStringDEC_Sim(b, 64), 64));
541  ASSERT_FALSE(strncmp("+180:00:00", p.toStringDEC(b, 64), 64));
543 
544  ASSERT_FALSE(p.parseStringDEC("+F5:00:00", 9));
545  ASSERT_EQ(+225.0, p.DECm());
546  ASSERT_FALSE(strncmp("+F5:00:00", p.toStringDEC_Sim(b, 64), 64));
547  ASSERT_FALSE(strncmp("+225:00:00", p.toStringDEC(b, 64), 64));
549 
550  ASSERT_FALSE(p.parseStringDEC("+I5:00:00", 9));
551  ASSERT_EQ(+255.0, p.DECm());
552  ASSERT_FALSE(strncmp("+I5:00:00", p.toStringDEC_Sim(b, 64), 64));
553  ASSERT_FALSE(strncmp("+255:00:00", p.toStringDEC(b, 64), 64));
555 
556  ASSERT_FALSE(p.parseStringDEC("+00:00:01", 9));
558  ASSERT_NEAR(+1 / 3600.0, p.DECm(), 1 / 3600.0);
559  ASSERT_FALSE(strncmp("+00:00:01", p.toStringDEC(b, 64), 64));
561  ASSERT_FALSE(p.parseStringDEC("+00:01:00", 9));
563  ASSERT_NEAR(+1 / 60.0, p.DECm(), 1 / 3600.0);
564  ASSERT_FALSE(strncmp("+00:01:00", p.toStringDEC(b, 64), 64));
566 
567  ASSERT_FALSE(p.parseStringDEC("-00:00:01", 9));
569  ASSERT_NEAR(-1 / 3600.0, p.DECm(), 1 / 3600.0);
570  ASSERT_FALSE(strncmp("+00:00:01", p.toStringDEC(b, 64), 64));
572  ASSERT_FALSE(p.parseStringDEC("-00:01:00", 9));
574  ASSERT_NEAR(-1 / 60.0, p.DECm(), 1 / 3600.0);
575  ASSERT_FALSE(strncmp("+00:01:00", p.toStringDEC(b, 64), 64));
577 
578  // Negative tests
579  ASSERT_TRUE(p.parseStringDEC("+J0:00:00", 9));
580  ASSERT_TRUE(p.parseStringDEC("-J0:00:00", 9));
581 }
582 
583 TEST(EQ500XDriverTest, test_Sync)
584 {
586  ASSERT_TRUE(d.isConnected());
587  ASSERT_TRUE(d.executeReadScopeStatus());
588 
590  ASSERT_FALSE(d.getCurrentMechanicalPosition(p));
591  ASSERT_EQ(0.0, p.RAm());
592  ASSERT_EQ(0.0, p.DECm());
593  ASSERT_EQ(0.0, p.RAsky());
594  ASSERT_EQ(90.0, p.DECsky());
596 
597  ASSERT_TRUE(d.executeSync(0, 0));
598  ASSERT_FALSE(d.getCurrentMechanicalPosition(p));
599  ASSERT_EQ(0.0, p.RAm());
600  ASSERT_EQ(90.0, p.DECm());
601  ASSERT_EQ(0.0, p.RAsky());
602  ASSERT_EQ(0.0, p.DECsky());
604 
605  ASSERT_TRUE(d.executeSync(10, 0));
606  ASSERT_FALSE(d.getCurrentMechanicalPosition(p));
607  ASSERT_EQ(10.0, p.RAm());
608  ASSERT_EQ(90.0, p.DECm());
609  ASSERT_EQ(10.0, p.RAsky());
610  ASSERT_EQ(0.0, p.DECsky());
612 
613  ASSERT_TRUE(d.executeSync(14, 0));
614  ASSERT_FALSE(d.getCurrentMechanicalPosition(p));
615  ASSERT_EQ(14.0, p.RAm());
616  ASSERT_EQ(90.0, p.DECm());
617  ASSERT_EQ(14.0, p.RAsky());
618  ASSERT_EQ(0.0, p.DECsky());
620 
621  ASSERT_TRUE(d.executeSync(0, 10));
622  ASSERT_FALSE(d.getCurrentMechanicalPosition(p));
623  ASSERT_EQ(0.0, p.RAm());
624  ASSERT_EQ(80.0, p.DECm());
625  ASSERT_EQ(0.0, p.RAsky());
626  ASSERT_EQ(10.0, p.DECsky());
628 
629  ASSERT_TRUE(d.executeSync(0, -10));
630  ASSERT_FALSE(d.getCurrentMechanicalPosition(p));
631  ASSERT_EQ(0.0, p.RAm());
632  ASSERT_EQ(100.0, p.DECm());
633  ASSERT_EQ(0.0, p.RAsky());
634  ASSERT_EQ(-10.0, p.DECsky());
636 
637  ASSERT_TRUE(d.executeSync(14, -10));
638  ASSERT_FALSE(d.getCurrentMechanicalPosition(p));
639  ASSERT_EQ(14.0, p.RAm());
640  ASSERT_EQ(100.0, p.DECm());
641  ASSERT_EQ(14.0, p.RAsky());
642  ASSERT_EQ(-10.0, p.DECsky());
644 }
645 
646 TEST(EQ500XDriverTest, test_Goto_NoMovement)
647 {
649  struct timespec timeout = {0, 100000000L};
650 
651  ASSERT_TRUE(d.isConnected());
652  ASSERT_TRUE(d.executeReadScopeStatus());
653  ASSERT_EQ(EQ500X::PIER_WEST, d.getPierSide());
654  ASSERT_TRUE(d.executeGotoOffset(0, 0));
655  ASSERT_EQ(EQ500X::SCOPE_SLEWING, d.getTrackState());
656  for(int i = 0; i < 10; i++)
657  {
658  nanosleep(&timeout, nullptr);
659  ASSERT_TRUE(d.executeReadScopeStatus());
660  if (EQ500X::SCOPE_TRACKING == d.getTrackState()) break;
661  ASSERT_EQ(EQ500X::SCOPE_SLEWING, d.getTrackState());
662  }
663  ASSERT_EQ(EQ500X::SCOPE_TRACKING, d.getTrackState());
664  ASSERT_EQ(EQ500X::PIER_WEST, d.getPierSide());
665 }
666 
667 TEST(EQ500XDriverTest, test_Goto_AbortMovement)
668 {
670 
671  ASSERT_TRUE(d.isConnected());
672  ASSERT_TRUE(d.executeReadScopeStatus());
673  ASSERT_TRUE(d.executeGotoOffset(-1, -10));
674  ASSERT_EQ(EQ500X::SCOPE_SLEWING, d.getTrackState());
675  for(int i = 0; i < 4; i++)
676  {
677  long seconds = d.getReadScopeStatusInterval() / 1000;
678  struct timespec timeout = {seconds, (d.getReadScopeStatusInterval() - seconds * 1000) * 1000000L};
679  nanosleep(&timeout, nullptr);
680  ASSERT_TRUE(d.executeReadScopeStatus());
681  ASSERT_EQ(EQ500X::SCOPE_SLEWING, d.getTrackState());
682  }
683  ASSERT_EQ(EQ500X::SCOPE_SLEWING, d.getTrackState());
684  ASSERT_TRUE(d.executeAbort());
685  ASSERT_EQ(EQ500X::SCOPE_TRACKING, d.getTrackState());
686  ASSERT_EQ(1000, d.getReadScopeStatusInterval());
687 }
688 
689 TEST(EQ500XDriverTest, test_Goto_SouthMovement)
690 {
692 
693  ASSERT_TRUE(d.isConnected());
694  ASSERT_TRUE(d.executeReadScopeStatus());
695  ASSERT_EQ(EQ500X::PIER_WEST, d.getPierSide());
696  ASSERT_TRUE(d.executeGotoOffset(0, -10));
697  ASSERT_EQ(EQ500X::SCOPE_SLEWING, d.getTrackState());
698  for(int i = 0; i < 150; i++)
699  {
700  long seconds = d.getReadScopeStatusInterval() / 1000;
701  struct timespec timeout = {seconds, (d.getReadScopeStatusInterval() - seconds * 1000) * 1000000L};
702  nanosleep(&timeout, nullptr);
703  ASSERT_TRUE(d.executeReadScopeStatus());
704  if (EQ500X::SCOPE_TRACKING == d.getTrackState()) break;
705  ASSERT_EQ(EQ500X::SCOPE_SLEWING, d.getTrackState());
706  }
707  ASSERT_EQ(EQ500X::SCOPE_TRACKING, d.getTrackState());
708  ASSERT_EQ(EQ500X::PIER_WEST, d.getPierSide());
709 }
710 
711 TEST(EQ500XDriverTest, test_Goto_NorthMovement)
712 {
714 
715  ASSERT_TRUE(d.isConnected());
716  ASSERT_TRUE(d.executeReadScopeStatus());
717  ASSERT_EQ(EQ500X::PIER_WEST, d.getPierSide());
718  ASSERT_TRUE(d.executeGotoOffset(0, +10));
719  ASSERT_EQ(EQ500X::SCOPE_SLEWING, d.getTrackState());
720  for(int i = 0; i < 150; i++)
721  {
722  long seconds = d.getReadScopeStatusInterval() / 1000;
723  struct timespec timeout = {seconds, (d.getReadScopeStatusInterval() - seconds * 1000) * 1000000L};
724  nanosleep(&timeout, nullptr);
725  ASSERT_TRUE(d.executeReadScopeStatus());
726  if (EQ500X::SCOPE_TRACKING == d.getTrackState()) break;
727  ASSERT_EQ(EQ500X::SCOPE_SLEWING, d.getTrackState());
728  }
729  ASSERT_EQ(EQ500X::SCOPE_TRACKING, d.getTrackState());
730  ASSERT_EQ(EQ500X::PIER_WEST, d.getPierSide());
731 }
732 
733 TEST(EQ500XDriverTest, test_Goto_EastMovement)
734 {
736 
737  ASSERT_TRUE(d.isConnected());
738  ASSERT_TRUE(d.executeReadScopeStatus());
739  ASSERT_EQ(EQ500X::PIER_WEST, d.getPierSide());
740  ASSERT_TRUE(d.executeGotoOffset(+1, 0));
741  ASSERT_EQ(EQ500X::SCOPE_SLEWING, d.getTrackState());
742  for(int i = 0; i < 150; i++)
743  {
744  long seconds = d.getReadScopeStatusInterval() / 1000;
745  struct timespec timeout = {seconds, (d.getReadScopeStatusInterval() - seconds * 1000) * 1000000L};
746  nanosleep(&timeout, nullptr);
747  ASSERT_TRUE(d.executeReadScopeStatus());
748  if (EQ500X::SCOPE_TRACKING == d.getTrackState()) break;
749  ASSERT_EQ(EQ500X::SCOPE_SLEWING, d.getTrackState());
750  }
751  ASSERT_EQ(EQ500X::SCOPE_TRACKING, d.getTrackState());
752  ASSERT_EQ(EQ500X::PIER_EAST, d.getPierSide());
753 }
754 
755 TEST(EQ500XDriverTest, test_Goto_WestMovement)
756 {
758 
759  ASSERT_TRUE(d.isConnected());
760  ASSERT_TRUE(d.executeReadScopeStatus());
761  ASSERT_EQ(EQ500X::PIER_WEST, d.getPierSide());
762  ASSERT_TRUE(d.executeGotoOffset(-1, 0));
763  ASSERT_EQ(EQ500X::SCOPE_SLEWING, d.getTrackState());
764  for(int i = 0; i < 150; i++)
765  {
766  long seconds = d.getReadScopeStatusInterval() / 1000;
767  struct timespec timeout = {seconds, (d.getReadScopeStatusInterval() - seconds * 1000) * 1000000L};
768  nanosleep(&timeout, nullptr);
769  ASSERT_TRUE(d.executeReadScopeStatus());
770  if (EQ500X::SCOPE_TRACKING == d.getTrackState()) break;
771  ASSERT_EQ(EQ500X::SCOPE_SLEWING, d.getTrackState());
772  }
773  ASSERT_EQ(EQ500X::SCOPE_TRACKING, d.getTrackState());
774  ASSERT_EQ(EQ500X::PIER_WEST, d.getPierSide());
775 }
776 
777 TEST(EQ500XDriverTest, test_RestoreSlewRateOnAbort)
778 {
780 
781  ASSERT_TRUE(d.isConnected());
782  ASSERT_TRUE(d.executeReadScopeStatus());
783  ASSERT_EQ(EQ500X::SLEW_FIND, d.getSlewRateIndex());
784  ASSERT_TRUE(d.executeGotoOffset(1, -1));
785  ASSERT_TRUE(d.executeReadScopeStatus());
786  long seconds = d.getReadScopeStatusInterval() / 1000;
787  struct timespec timeout = {seconds, (d.getReadScopeStatusInterval() - seconds * 1000) * 1000000L};
788  nanosleep(&timeout, nullptr);
789  ASSERT_TRUE(d.executeReadScopeStatus());
790  ASSERT_EQ(EQ500X::SCOPE_SLEWING, d.getTrackState());
791  ASSERT_TRUE(d.executeAbort());
792  ASSERT_EQ(EQ500X::SCOPE_TRACKING, d.getTrackState());
793  ASSERT_EQ(EQ500X::SLEW_FIND, d.getSlewRateIndex());
794 }
795 
796 TEST(EQ500XDriverTest, test_RestoreSlewRateAfterGoto)
797 {
799 
800  ASSERT_TRUE(d.isConnected());
801  ASSERT_TRUE(d.executeReadScopeStatus());
802  ASSERT_EQ(EQ500X::SLEW_FIND, d.getSlewRateIndex());
803  ASSERT_TRUE(d.executeGotoOffset(1, -1));
804  ASSERT_TRUE(d.executeReadScopeStatus());
805  for(int i = 0; i < 150; i++)
806  {
807  long seconds = d.getReadScopeStatusInterval() / 1000;
808  struct timespec timeout = {seconds, (d.getReadScopeStatusInterval() - seconds * 1000) * 1000000L};
809  nanosleep(&timeout, nullptr);
810  ASSERT_TRUE(d.executeReadScopeStatus());
812  {
813  ASSERT_EQ(EQ500X::SLEW_FIND, d.getSlewRateIndex());
814  return;
815  }
816  }
817  ASSERT_FALSE(true);
818 }
819 
820 TEST(EQ500XDriverTest, test_RestoreSlewRateAfterInterruptingGoto)
821 {
823 
824  ASSERT_TRUE(d.isConnected());
825  ASSERT_TRUE(d.executeReadScopeStatus());
826  ASSERT_EQ(EQ500X::SLEW_FIND, d.getSlewRateIndex());
827  ASSERT_TRUE(d.executeGotoOffset(1, -1));
828  ASSERT_TRUE(d.executeReadScopeStatus());
829  for(int i = 0; i < 30; i++)
830  {
831  long seconds = d.getReadScopeStatusInterval() / 1000;
832  struct timespec timeout = {seconds, (d.getReadScopeStatusInterval() - seconds * 1000) * 1000000L};
833  nanosleep(&timeout, nullptr);
834  ASSERT_TRUE(d.executeReadScopeStatus());
835  }
836  ASSERT_EQ(EQ500X::SCOPE_SLEWING, d.getTrackState());
837  ASSERT_TRUE(d.executeGotoOffset(1, -1));
838  for(int i = 0; i < 150; i++)
839  {
840  long seconds = d.getReadScopeStatusInterval() / 1000;
841  struct timespec timeout = {seconds, (d.getReadScopeStatusInterval() - seconds * 1000) * 1000000L};
842  nanosleep(&timeout, nullptr);
843  ASSERT_TRUE(d.executeReadScopeStatus());
845  {
846  ASSERT_EQ(EQ500X::SLEW_FIND, d.getSlewRateIndex());
847  return;
848  }
849  }
850  ASSERT_FALSE(true);
851 }
852 
853 int main(int argc, char **argv)
854 {
857 
858  ::testing::InitGoogleTest(&argc, argv);
859  ::testing::InitGoogleMock(&argc, argv);
860  return RUN_ALL_TESTS();
861 }
double DECsky() const
Definition: eq500x.cpp:955
enum PointingState setPointingState(enum PointingState)
Definition: eq500x.cpp:1272
char const * toStringDEC_Sim(char *, size_t) const
Definition: eq500x.cpp:1028
double DECm() const
Definition: eq500x.cpp:918
enum PointingState getPointingState() const
Definition: eq500x.cpp:1278
bool parseStringRA(char const *, size_t)
Definition: eq500x.cpp:1008
double RA_degrees_to(MechanicalPoint const &) const
Definition: eq500x.cpp:1236
double RAm() const
Definition: eq500x.cpp:913
char const * toStringDEC(char *, size_t) const
Definition: eq500x.cpp:1107
double RAsky() const
Definition: eq500x.cpp:943
bool parseStringDEC(char const *, size_t)
Definition: eq500x.cpp:1123
char const * toStringRA(char *, size_t) const
Definition: eq500x.cpp:994
Definition: eq500x.h:29
virtual bool updateLocation(double, double, double) override
Update telescope location settings.
Definition: eq500x.cpp:227
virtual bool checkConnection() override
Definition: eq500x.cpp:165
virtual bool Goto(double, double) override
Move the scope to the supplied RA and DEC coordinates.
Definition: eq500x.cpp:603
virtual bool ReadScopeStatus() override
Read telescope status.
Definition: eq500x.cpp:249
virtual bool Sync(double, double) override
Set the telescope current RA and DEC coordinates to the supplied RA and DEC coordinates.
Definition: eq500x.cpp:691
bool getCurrentMechanicalPosition(MechanicalPoint &)
Definition: eq500x.cpp:833
void resetSimulation()
Definition: eq500x.cpp:137
virtual bool Abort() override
Abort any telescope motion including tracking if possible.
Definition: eq500x.cpp:734
bool isConnected() const
Definition: basedevice.cpp:520
void setSimulation(bool enable)
Toggle driver simulation status A driver can run in simulation mode if Simulation option is enabled b...
virtual void setConnected(bool status, IPState state=IPS_OK, const char *msg=nullptr)
Set connection switch status in the client.
uint32_t getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
TelescopeStatus TrackState
ISwitchVectorProperty SlewRateSP
TelescopePierSide getPierSide()
virtual void ISGetProperties(const char *dev) override
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
long getReadScopeStatusInterval() const
bool executeGotoOffset(double ra_offset, double dec_offset)
bool getCurrentMechanicalPosition(MechanicalPoint &p)
int getSlewRateIndex() const
void setLongitude(double lng)
bool executeSync(double ra, double dec)
TelescopeStatus getTrackState() const
double ra
double dec
Implementations for common driver routines.
int IUFindOnSwitchIndex(const ISwitchVectorProperty *svp)
Returns the index of first ON switch it finds in the vector switch property.
Definition: indidevapi.c:128
static const loggerConf file_off
Definition: indilogger.h:219
void configure(const std::string &outputFile, const loggerConf configuration, const int fileVerbosityLevel, const int screenVerbosityLevel)
Method to configure the logger. Called by the DEBUG_CONF() macro. To make implementation easier,...
Definition: indilogger.cpp:283
static Logger & getInstance()
Method to get a reference to the object (i.e., Singleton) It is a static method.
Definition: indilogger.cpp:339
TEST(EQ500XDriverTest, test_LSTSync)
int main(int argc, char **argv)
char _me[]
char * me