moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / kstars / kstars / indi / mount_simulation.c
blobc6630f0a737c5473a82b0c4da2cbb9e9eea2ed48
1 #if 0
2 INDI
3 Copyright (C) 2003 Elwood C. Downey
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #endif
21 /* simulate a telescope mount on an INDI interface.
22 * it can be told to slew to an RA or Dec and will go there slowly enough to
23 * watch.
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <stdarg.h>
30 //#include <math.h>
31 #include <sys/time.h>
32 #include <unistd.h>
34 #include "indiapi.h"
36 static void sendeq (char *msg);
37 static void sendNewPow (void);
38 static void mountSim (void *);
40 #define SLEWRATE 1 /* slew rate, degrees/s */
41 #define POLLMS 250 /* poll period, ms */
42 #define SIDRATE 0.004178 /* sidereal rate, degrees/s */
45 /* INDI controls */
47 static char mydev[] = "Telescope Simulator"; /* our Device name */
49 /* equatorial position */
50 static INumber eq[] = {
51 {"RA", "RA H:M:S", "%10.6m", 0., 24., 0., 0.},
52 {"DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0.},
54 static INumberVectorProperty eqNum = {
55 mydev, "EQUATORIAL_COORD", "Equatorial J2000", NULL, IP_RW, 0, IPS_IDLE,
56 eq, NARRAY(eq),
59 /* main power switch */
60 static ISwitch power[] = {
61 {"CONNECT", "On", ISS_OFF},
63 static ISwitchVectorProperty powSw = {
64 mydev, "CONNECTION", "Connection", NULL, IP_RW, ISR_1OFMANY, 0., IPS_IDLE,
65 power, NARRAY(power),
68 /* operational info */
69 static double targetRA;
70 static double targetDEC;
71 static double currentRA; /* scope's current simulated RA, rads */
72 static double currentDec; /* scope's current simulated Dec, rads */
74 /* call first, then benign there after */
75 static void
76 mountInit()
78 static int inited; /* set once mountInit is called */
80 if (inited)
81 return;
83 /* start timer to simulate mount motion */
84 IEAddTimer (POLLMS, mountSim, NULL);
86 inited = 1;
90 /* send client definitions of all properties */
91 void
92 ISGetProperties (const char *dev)
94 if (dev && strcmp (mydev, dev))
95 return;
97 IDDefNumber (&eqNum, NULL);
98 IDDefSwitch (&powSw, NULL);
101 void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
104 /* client is sending us a new value for a Numeric vector property */
105 void
106 ISNewNumber (const char *dev, const char *name, double values[],
107 char *names[], int n)
109 char msg[64];
111 /* ignore if not ours */
112 if (strcmp (dev, mydev))
113 return;
115 mountInit();
117 if (!strcmp (name, eqNum.name)) {
118 /* new equatorial target coords */
119 double newra = 0, newdec = 0;
120 int i, nset;
121 if (power[0].s != ISS_ON) {
122 eqNum.s = IPS_IDLE;
123 sendeq ("Power is off");
124 return;
126 for (nset = i = 0; i < n; i++) {
127 INumber *eqp = IUFindNumber (&eqNum, names[i]);
128 if (eqp == &eq[0]) {
129 newra = (values[i]);
130 nset += newra >= 0 && newra <= 24;
131 } else if (eqp == &eq[1]) {
132 newdec = (values[i]);
133 nset += newdec >= -90 && newdec <= 90;
136 if (nset == 2) {
137 char r[32], d[32];
138 eqNum.s = IPS_BUSY;
139 targetRA = newra;
140 targetDEC = newdec;
141 fs_sexa (r, targetRA, 2, 3600);
142 fs_sexa (d, targetDEC, 3, 3600);
143 snprintf (msg, sizeof(msg), "Moving to RA Dec %.32s %.32s", r, d);
144 } else {
145 eqNum.s = IPS_IDLE;
146 snprintf (msg, sizeof(msg), "RA or Dec absent or bogus");
148 sendeq (msg);
149 return;
153 /* client is sending us a new value for a Switch property */
154 void
155 ISNewSwitch (const char *dev, const char *name, ISState *states,
156 char *names[], int n)
158 ISwitch *sp;
160 /* ignore if not ours */
161 if (strcmp (dev, mydev))
162 return;
164 IDLog("Before mount init \n");
165 mountInit();
167 IDLog("before find switch\n");
168 sp = IUFindSwitch (&powSw, names[0]);
170 IDLog("after find switch\n");
172 if (sp) {
173 sp->s = states[0];
174 sendNewPow ();
177 IDLog("after send now\n");
178 /*powSw.sw[0].s = states[0];*/
181 /* update the "mount" over time */
182 void
183 mountSim (void *p)
185 static struct timeval ltv;
186 struct timeval tv;
187 double dt, da, dx;
188 int nlocked;
190 /* update elapsed time since last poll, don't presume exactly POLLMS */
191 gettimeofday (&tv, NULL);
192 if (ltv.tv_sec == 0 && ltv.tv_usec == 0)
193 ltv = tv;
194 dt = tv.tv_sec - ltv.tv_sec + (tv.tv_usec - ltv.tv_usec)/1e6;
195 ltv = tv;
196 da = SLEWRATE*dt;
198 /* process per current state */
199 switch (eqNum.s)
201 case IPS_IDLE:
202 /* RA moves at sidereal, Dec stands still */
203 currentRA += (SIDRATE*dt/15.);
204 sendeq (NULL);
205 break;
207 case IPS_BUSY:
208 /* slewing - nail it when both within one pulse @ SLEWRATE */
209 nlocked = 0;
211 dx = targetRA - currentRA;
212 if (fabs(dx) <= da)
214 currentRA = targetRA;
215 nlocked++;
217 else if (dx > 0)
218 currentRA += da/15.;
219 else
220 currentRA -= da/15.;
223 dx = targetDEC - currentDec;
224 if (fabs(dx) <= da)
226 currentDec = targetDEC;
227 nlocked++;
229 else if (dx > 0)
230 currentDec += da;
231 else
232 currentDec -= da;
234 if (nlocked == 2)
236 eqNum.s = IPS_OK;
237 sendeq("Now tracking");
238 } else
239 sendeq(NULL);
241 break;
243 case IPS_OK:
244 /* tracking */
245 sendeq (NULL);
246 break;
248 case IPS_ALERT:
249 break;
252 /* again */
253 IEAddTimer (POLLMS, mountSim, NULL);
256 /* set eqNum from currentRA and Dec and send to client with optional message */
257 static void
258 sendeq (char *msg)
260 eq[0].value = currentRA;
261 eq[1].value = currentDec;
262 IDSetNumber (&eqNum, msg);
265 static void
266 sendNewPow ()
268 if (power[0].s == ISS_ON) {
269 powSw.s = IPS_OK;
270 IDSetSwitch (&powSw, "Power on");
271 eqNum.s = IPS_OK;
272 } else {
273 powSw.s = IPS_IDLE;
274 IDSetSwitch (&powSw, "Power off");
275 eqNum.s = IPS_IDLE;
276 sendeq (NULL);