Instrument Neutral Distributed Interface INDI 2.2.5
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
22using ::testing::_;
23using ::testing::StrEq;
24
25char _me[] = "MockEQ500XDriver";
26char *me = _me;
28{
29 public:
31 {
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 }
54 {
55 return TrackState;
56 }
58 {
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 }
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
113TEST(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
137TEST(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
167TEST(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
193TEST(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
235TEST(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
263TEST(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
299TEST(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
335TEST(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
390TEST(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
473TEST(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
583TEST(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
646TEST(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 }
664 ASSERT_EQ(EQ500X::PIER_WEST, d.getPierSide());
665}
666
667TEST(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());
686 ASSERT_EQ(1000, d.getReadScopeStatusInterval());
687}
688
689TEST(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 }
708 ASSERT_EQ(EQ500X::PIER_WEST, d.getPierSide());
709}
710
711TEST(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 }
730 ASSERT_EQ(EQ500X::PIER_WEST, d.getPierSide());
731}
732
733TEST(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 }
752 ASSERT_EQ(EQ500X::PIER_EAST, d.getPierSide());
753}
754
755TEST(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 }
774 ASSERT_EQ(EQ500X::PIER_WEST, d.getPierSide());
775}
776
777TEST(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());
793 ASSERT_EQ(EQ500X::SLEW_FIND, d.getSlewRateIndex());
794}
795
796TEST(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
820TEST(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
853int 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:962
enum PointingState setPointingState(enum PointingState)
Definition eq500x.cpp:1279
char const * toStringDEC_Sim(char *, size_t) const
Definition eq500x.cpp:1035
double DECm() const
Definition eq500x.cpp:925
enum PointingState getPointingState() const
Definition eq500x.cpp:1285
bool parseStringRA(char const *, size_t)
Definition eq500x.cpp:1015
double RA_degrees_to(MechanicalPoint const &) const
Definition eq500x.cpp:1243
double RAm() const
Definition eq500x.cpp:920
char const * toStringDEC(char *, size_t) const
Definition eq500x.cpp:1114
double RAsky() const
Definition eq500x.cpp:950
bool parseStringDEC(char const *, size_t)
Definition eq500x.cpp:1130
char const * toStringRA(char *, size_t) const
Definition eq500x.cpp:1001
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:605
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:696
bool getCurrentMechanicalPosition(MechanicalPoint &)
Definition eq500x.cpp:840
void resetSimulation()
Definition eq500x.cpp:137
virtual bool Abort() override
Abort any telescope motion including tracking if possible.
Definition eq500x.cpp:740
bool isConnected() const
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
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
int main()
INDI::PropertySwitch SlewRateSP
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:337
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,...
static Logger & getInstance()
Method to get a reference to the object (i.e., Singleton) It is a static method.
TEST(EQ500XDriverTest, test_LSTSync)
char _me[]
char * me