moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / kstars / kstars / indi / lx200_16.cpp
blob03e2cc45244ecbe2a2b6c13504360f0a3f506db0
1 /*
2 LX200 16"
3 Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com)
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
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <math.h>
27 #include "lx200_16.h"
28 #include "lx200driver.h"
30 #define LX16GROUP "GPS/16 inch Features"
32 extern LX200Generic *telescope;
33 extern ITextVectorProperty Time;
34 extern int MaxReticleFlashRate;
37 //void turnFanOn();
38 //void turnFanOff();
40 //void seekHomeAndSave();
41 // void seekHomeAndSet();
43 /** Turns the field derotator On or Off. This command applies <b>only</b> to 16" LX200.
44 @param turnOn if turnOn is true, the derotator is turned on, otherwise, it is turned off. */
45 // void fieldDeRotator(bool turnOn);
48 /** Sets object Altitude. \n
49 @returns true if object's altitude is successfully set. */
50 //bool setObjAlt(int degrees, int minutes);
52 /** Sets object Azimuth. \n
53 @returns true if object's azimuth is successfully set. */
54 // bool setObjAz(int degrees, int minutes);
57 static ISwitch FanStatusS[] = { {"On", "", ISS_OFF, 0, 0}, {"Off", "", ISS_OFF, 0, 0}};
58 static ISwitch HomeSearchS[] = { {"Save home", "", ISS_OFF, 0, 0} , {"Set home", "", ISS_OFF, 0, 0}};
59 static ISwitch FieldDeRotatorS[] = { {"On", "", ISS_OFF, 0, 0}, {"Off", "", ISS_OFF,0 ,0}};
60 //static ISwitch SlewAltAzS[] = { {"Slew To Alt/Az", ISS_ON}};
62 #define MAXINDINAME 32
63 #define MAXINDILABEL 32
64 #define MAXINDIDEVICE 32
65 #define MAXINDIGROUP 32
66 #define MAXINDIFORMAT 32
68 static ISwitchVectorProperty FanStatusSw = { mydev, "Fan", "", LX16GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, FanStatusS, NARRAY(FanStatusS), "", 0};
70 static ISwitchVectorProperty HomeSearchSw = { mydev, "Park", "", LX16GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, HomeSearchS, NARRAY(HomeSearchS), "", 0};
72 static ISwitchVectorProperty FieldDeRotatorSw = { mydev, "Field De-rotator", "", LX16GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, FieldDeRotatorS, NARRAY(FieldDeRotatorS), "", 0};
74 //static ISwitches SlewAltAzSw = { mydev, "AltAzSet", "On Alt/Az Set", SlewAltAzS, NARRAY(SlewAltAzS), ILS_IDLE, 0, LX16Group};
76 /* horizontal position */
77 static INumber hor[] = {
78 {"ALT", "Alt D:M:S", "%10.6m", -90., 90., 0., 0., 0, 0, 0},
79 {"AZ", "Az D:M:S", "%10.6m", 0., 360., 0., 0., 0, 0, 0}};
81 static INumberVectorProperty horNum = {
82 mydev, "HORIZONTAL_COORD", "Horizontal Coords", LX16GROUP, IP_RW, 0, IPS_IDLE,
83 hor, NARRAY(hor), "", 0};
85 void changeLX200_16DeviceName(const char * newName)
87 strcpy(horNum.device, newName);
88 strcpy(FanStatusSw.device, newName);
89 strcpy(HomeSearchSw.device, newName);
90 strcpy(FieldDeRotatorSw.device,newName);
93 LX200_16::LX200_16() : LX200Autostar()
98 void LX200_16::ISGetProperties (const char *dev)
101 if (dev && strcmp (thisDevice, dev))
102 return;
104 // process parent first
105 LX200Autostar::ISGetProperties(dev);
107 IDDefNumber (&horNum, NULL);
109 IDDefSwitch (&FanStatusSw, NULL);
110 IDDefSwitch (&HomeSearchSw, NULL);
111 IDDefSwitch (&FieldDeRotatorSw, NULL);
115 void LX200_16::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
118 // ignore if not ours //
119 if (strcmp (dev, thisDevice))
120 return;
122 LX200Autostar::ISNewText (dev, name, texts, names, n);
126 void LX200_16::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
128 double newAlt=0, newAz=0;
129 char altStr[64], azStr[64];
130 int err;
132 // ignore if not ours //
133 if (strcmp (dev, thisDevice))
134 return;
136 if ( !strcmp (name, horNum.name) )
138 int i=0, nset=0;
140 if (checkPower(&horNum))
141 return;
143 for (nset = i = 0; i < n; i++)
145 INumber *horp = IUFindNumber (&horNum, names[i]);
146 if (horp == &hor[0])
148 newAlt = values[i];
149 nset += newAlt >= -90. && newAlt <= 90.0;
150 } else if (horp == &hor[1])
152 newAz = values[i];
153 nset += newAz >= 0. && newAz <= 360.0;
157 if (nset == 2)
159 if ( (err = setObjAz(newAz)) < 0 || (err = setObjAlt(newAlt)) < 0)
161 handleError(&horNum, err, "Setting Alt/Az");
162 return;
164 horNum.s = IPS_OK;
165 //horNum.n[0].value = values[0];
166 //horNum.n[1].value = values[1];
167 targetAz = newAz;
168 targetAlt = newAlt;
170 fs_sexa(azStr, targetAz, 2, 3600);
171 fs_sexa(altStr, targetAlt, 2, 3600);
173 IDSetNumber (&horNum, "Attempting to slew to Alt %s - Az %s", altStr, azStr);
174 handleAltAzSlew();
176 else
178 horNum.s = IPS_IDLE;
179 IDSetNumber(&horNum, "Altitude or Azimuth missing or invalid");
182 return;
185 LX200Autostar::ISNewNumber (dev, name, values, names, n);
191 void LX200_16::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
193 int index;
194 int err;
196 if (strcmp (dev, thisDevice))
197 return;
199 if (!strcmp(name, FanStatusSw.name))
201 if (checkPower(&FanStatusSw))
202 return;
204 IUResetSwitches(&FanStatusSw);
205 IUUpdateSwitches(&FanStatusSw, states, names, n);
206 index = getOnSwitch(&FanStatusSw);
208 if (index == 0)
210 if ( (err = turnFanOn()) < 0)
212 handleError(&FanStatusSw, err, "Changing fan status");
213 return;
216 else
218 if ( (err = turnFanOff()) < 0)
220 handleError(&FanStatusSw, err, "Changing fan status");
221 return;
225 FanStatusSw.s = IPS_OK;
226 IDSetSwitch (&FanStatusSw, index == 0 ? "Fan is ON" : "Fan is OFF");
227 return;
230 if (!strcmp(name, HomeSearchSw.name))
232 if (checkPower(&HomeSearchSw))
233 return;
235 IUResetSwitches(&HomeSearchSw);
236 IUUpdateSwitches(&HomeSearchSw, states, names, n);
237 index = getOnSwitch(&HomeSearchSw);
239 index == 0 ? seekHomeAndSave() : seekHomeAndSet();
240 HomeSearchSw.s = IPS_BUSY;
241 IDSetSwitch (&HomeSearchSw, index == 0 ? "Seek Home and Save" : "Seek Home and Set");
242 return;
245 if (!strcmp(name, FieldDeRotatorSw.name))
247 if (checkPower(&FieldDeRotatorSw))
248 return;
250 IUResetSwitches(&FieldDeRotatorSw);
251 IUUpdateSwitches(&FieldDeRotatorSw, states, names, n);
252 index = getOnSwitch(&FieldDeRotatorSw);
254 index == 0 ? seekHomeAndSave() : seekHomeAndSet();
255 FieldDeRotatorSw.s = IPS_OK;
256 IDSetSwitch (&FieldDeRotatorSw, index == 0 ? "Field deRotator is ON" : "Field deRotator is OFF");
257 return;
260 LX200Autostar::ISNewSwitch (dev, name, states, names, n);
264 void LX200_16::handleAltAzSlew()
266 int i=0;
267 char altStr[64], azStr[64];
269 if (horNum.s == IPS_BUSY)
271 abortSlew();
273 // sleep for 100 mseconds
274 usleep(100000);
277 if ((i = slewToAltAz()))
279 horNum.s = IPS_IDLE;
280 IDSetNumber(&horNum, "Slew not possible");
281 return;
284 horNum.s = IPS_BUSY;
285 fs_sexa(azStr, targetAz, 2, 3600);
286 fs_sexa(altStr, targetAlt, 2, 3600);
288 IDSetNumber(&horNum, "Slewing to Alt %s - Az %s", altStr, azStr);
289 return;
292 void LX200_16::ISPoll ()
294 int searchResult=0;
295 double dx, dy;
296 int err;
298 LX200Autostar::ISPoll();
300 switch (HomeSearchSw.s)
302 case IPS_IDLE:
303 break;
305 case IPS_BUSY:
307 if ( (err = getHomeSearchStatus(&searchResult)) < 0)
309 handleError(&HomeSearchSw, err, "Home search");
310 return;
313 if (searchResult == 0)
315 HomeSearchSw.s = IPS_IDLE;
316 IDSetSwitch(&HomeSearchSw, "Home search failed.");
318 else if (searchResult == 1)
320 HomeSearchSw.s = IPS_OK;
321 IDSetSwitch(&HomeSearchSw, "Home search successful.");
323 else if (searchResult == 2)
324 IDSetSwitch(&HomeSearchSw, "Home search in progress...");
325 else
327 HomeSearchSw.s = IPS_IDLE;
328 IDSetSwitch(&HomeSearchSw, "Home search error.");
330 break;
332 case IPS_OK:
333 break;
334 case IPS_ALERT:
335 break;
338 switch (horNum.s)
340 case IPS_IDLE:
341 break;
343 case IPS_BUSY:
345 if ( (err = getLX200Az(&currentAz)) < 0 || (err = getLX200Alt(&currentAlt)) < 0)
347 IDSetNumber(&horNum, NULL);
348 handleError(&horNum, err, "Get Alt/Az");
349 return;
352 dx = targetAz - currentAz;
353 dy = targetAlt - currentAlt;
355 horNum.np[0].value = currentAlt;
356 horNum.np[1].value = currentAz;
358 IDLog("targetAz is %g, currentAz is %g\n", targetAz, currentAz);
359 IDLog("targetAlt is %g, currentAlt is %g\n**********************\n", targetAlt, currentAlt);
362 // accuracy threshhold (3'), can be changed as desired.
363 if ( fabs(dx) <= 0.05 && fabs(dy) <= 0.05)
366 horNum.s = IPS_OK;
367 currentAz = targetAz;
368 currentAlt = targetAlt;
369 IDSetNumber (&horNum, "Slew is complete");
370 } else
371 IDSetNumber (&horNum, NULL);
372 break;
374 case IPS_OK:
375 break;
377 case IPS_ALERT:
378 break;
383 void LX200_16::getBasicData()
386 getLX200Az(&targetAz);
387 getLX200Alt(&targetAlt);
389 horNum.np[0].value = targetAlt;
390 horNum.np[1].value = targetAz;
392 IDSetNumber (&horNum, NULL);
394 LX200Autostar::getBasicData();