Instrument Neutral Distributed Interface INDI  2.0.2
simplescope.cpp
Go to the documentation of this file.
1 /*
2  INDI Developers Manual
3  Tutorial #2
4 
5  "Simple Telescope Driver"
6 
7  We develop a simple telescope simulator.
8 
9  Refer to README, which contains instruction on how to build this driver, and use it
10  with an INDI-compatible client.
11 
12 */
13 
22 #include "simplescope.h"
23 
24 #include "indicom.h"
25 
26 #include <cmath>
27 #include <memory>
28 
29 static std::unique_ptr<SimpleScope> simpleScope(new SimpleScope());
30 
32 {
33  // We add an additional debug level so we can log verbose scope status
34  DBG_SCOPE = INDI::Logger::getInstance().addDebugLevel("Scope Verbose", "SCOPE");
35 }
36 
37 /**************************************************************************************
38 ** We init our properties here. The only thing we want to init are the Debug controls
39 ***************************************************************************************/
41 {
42  // ALWAYS call initProperties() of parent first
44 
45  // Add Debug control so end user can turn debugging/loggin on and off
47 
48  // Enable simulation mode so that serial connection in INDI::Telescope does not try
49  // to attempt to perform a physical connection to the serial port.
50  setSimulation(true);
51 
52  // Set telescope capabilities. 0 is for the the number of slew rates that we support. We have none for this simple driver.
54 
55  return true;
56 }
57 
58 /**************************************************************************************
59 ** INDI is asking us to check communication with the device via a handshake
60 ***************************************************************************************/
62 {
63  // When communicating with a real mount, we check here if commands are receieved
64  // and acknolowedged by the mount. For SimpleScope, we simply return true.
65  return true;
66 }
67 
68 /**************************************************************************************
69 ** INDI is asking us for our default device name
70 ***************************************************************************************/
72 {
73  return "Simple Scope";
74 }
75 
76 /**************************************************************************************
77 ** Client is asking us to slew to a new position
78 ***************************************************************************************/
79 bool SimpleScope::Goto(double ra, double dec)
80 {
81  targetRA = ra;
82  targetDEC = dec;
83  char RAStr[64] = {0}, DecStr[64] = {0};
84 
85  // Parse the RA/DEC into strings
86  fs_sexa(RAStr, targetRA, 2, 3600);
87  fs_sexa(DecStr, targetDEC, 2, 3600);
88 
89  // Mark state as slewing
91 
92  // Inform client we are slewing to a new position
93  LOGF_INFO("Slewing to RA: %s - DEC: %s", RAStr, DecStr);
94 
95  // Success!
96  return true;
97 }
98 
99 /**************************************************************************************
100 ** Client is asking us to abort our motion
101 ***************************************************************************************/
103 {
104  return true;
105 }
106 
107 /**************************************************************************************
108 ** Client is asking us to report telescope status
109 ***************************************************************************************/
111 {
112  static struct timeval ltv
113  {
114  0, 0
115  };
116  struct timeval tv
117  {
118  0, 0
119  };
120  double dt = 0, da_ra = 0, da_dec = 0, dx = 0, dy = 0;
121  int nlocked;
122 
123  /* update elapsed time since last poll, don't presume exactly POLLMS */
124  gettimeofday(&tv, nullptr);
125 
126  if (ltv.tv_sec == 0 && ltv.tv_usec == 0)
127  ltv = tv;
128 
129  dt = tv.tv_sec - ltv.tv_sec + (tv.tv_usec - ltv.tv_usec) / 1e6;
130  ltv = tv;
131 
132  // Calculate how much we moved since last time
133  da_ra = SLEW_RATE * dt;
134  da_dec = SLEW_RATE * dt;
135 
136  /* Process per current state. We check the state of EQUATORIAL_EOD_COORDS_REQUEST and act acoordingly */
137  switch (TrackState)
138  {
139  case SCOPE_SLEWING:
140  // Wait until we are "locked" into positon for both RA & DEC axis
141  nlocked = 0;
142 
143  // Calculate diff in RA
144  dx = targetRA - currentRA;
145 
146  // If diff is very small, i.e. smaller than how much we changed since last time, then we reached target RA.
147  if (fabs(dx) * 15. <= da_ra)
148  {
149  currentRA = targetRA;
150  nlocked++;
151  }
152  // Otherwise, increase RA
153  else if (dx > 0)
154  currentRA += da_ra / 15.;
155  // Otherwise, decrease RA
156  else
157  currentRA -= da_ra / 15.;
158 
159  // Calculate diff in DEC
160  dy = targetDEC - currentDEC;
161 
162  // If diff is very small, i.e. smaller than how much we changed since last time, then we reached target DEC.
163  if (fabs(dy) <= da_dec)
164  {
165  currentDEC = targetDEC;
166  nlocked++;
167  }
168  // Otherwise, increase DEC
169  else if (dy > 0)
170  currentDEC += da_dec;
171  // Otherwise, decrease DEC
172  else
173  currentDEC -= da_dec;
174 
175  // Let's check if we recahed position for both RA/DEC
176  if (nlocked == 2)
177  {
178  // Let's set state to TRACKING
180 
181  LOG_INFO("Telescope slew is complete. Tracking...");
182  }
183  break;
184 
185  default:
186  break;
187  }
188 
189  char RAStr[64] = {0}, DecStr[64] = {0};
190 
191  // Parse the RA/DEC into strings
192  fs_sexa(RAStr, currentRA, 2, 3600);
193  fs_sexa(DecStr, currentDEC, 2, 3600);
194 
195  DEBUGF(DBG_SCOPE, "Current RA: %s Current DEC: %s", RAStr, DecStr);
196 
197  NewRaDec(currentRA, currentDEC);
198  return true;
199 }
void setSimulation(bool enable)
Toggle driver simulation status A driver can run in simulation mode if Simulation option is enabled b...
void addDebugControl()
Add Debug control to the driver.
TelescopeStatus TrackState
void SetTelescopeCapability(uint32_t cap, uint8_t slewRateCount)
SetTelescopeCapability sets the Telescope capabilities. All capabilities must be initialized.
virtual bool initProperties() override
Called to initialize basic properties required all the time.
void NewRaDec(double ra, double dec)
The child class calls this function when it has updates.
bool Handshake() override
perform handshake with device to check communication
Definition: simplescope.cpp:61
bool Goto(double, double) override
Move the scope to the supplied RA and DEC coordinates.
Definition: simplescope.cpp:79
const char * getDefaultName() override
Definition: simplescope.cpp:71
bool Abort() override
Abort any telescope motion including tracking if possible.
bool initProperties() override
Called to initialize basic properties required all the time.
Definition: simplescope.cpp:40
bool ReadScopeStatus() override
Read telescope status.
#define currentDEC
Definition: ieq45.cpp:48
#define currentRA
Definition: ieq45.cpp:47
double ra
double dec
int fs_sexa(char *out, double a, int w, int fracbase)
Converts a sexagesimal number to a string. sprint the variable a in sexagesimal format into out[].
Definition: indicom.c:141
Implementations for common driver routines.
#define LOGF_INFO(fmt,...)
Definition: indilogger.h:82
#define LOG_INFO(txt)
Definition: indilogger.h:74
#define DEBUGF(priority, msg,...)
Definition: indilogger.h:57
Construct a basic INDI telescope device that simulates GOTO commands.
static Logger & getInstance()
Method to get a reference to the object (i.e., Singleton) It is a static method.
Definition: indilogger.cpp:339
int addDebugLevel(const char *debugLevelName, const char *LoggingLevelName)
Adds a new debugging level to the driver.
Definition: indilogger.cpp:72