source: BAORadio/libindi/libindi/drivers/telescope/magellan1.cpp @ 646

Last change on this file since 646 was 646, checked in by frichard, 12 years ago
File size: 14.1 KB
Line 
1#if 0
2    MAGELLAN Generic
3    Copyright (C) 2011 Onno Hommes (ohommes@alumni.cmu.edu)
4
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.
9
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.
14
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18
19#endif
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <stdarg.h>
25#include <math.h>
26#include <unistd.h>
27#include <time.h>
28#include <sys/time.h>
29
30#include "magellandriver.h"
31#include "magellan1.h"
32
33#include <config.h>
34
35Magellan1 *telescope = NULL;
36
37extern char* me;
38
39#define COMM_GROUP      "Communication"
40#define BASIC_GROUP     "Position"
41
42#define MAGELLAN_TRACK  0
43#define MAGELLAN_SYNC   1
44
45/* Handy Macros */
46#define currentRA       EquatorialCoordsRN[0].value
47#define currentDEC      EquatorialCoordsRN[1].value
48#define targetRA        EquatorialCoordsWN[0].value
49#define targetDEC       EquatorialCoordsWN[1].value
50
51static void ISPoll(void *);
52static void retryConnection(void *);
53
54/*INDI Propertries */
55
56/**********************************************************************************************/
57/************************************ GROUP: Communication ************************************/
58/**********************************************************************************************/
59
60/********************************************
61 Property: Connection
62*********************************************/
63static ISwitch ConnectS[]               = {{"CONNECT" , "Connect" , ISS_OFF, 0, 0},{"DISCONNECT", "Disconnect", ISS_ON, 0, 0}};
64ISwitchVectorProperty ConnectSP         = { mydev, "CONNECTION" , "Connection", COMM_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, ConnectS, NARRAY(ConnectS), "", 0};
65
66/********************************************
67 Property: Device Port
68*********************************************/
69/*wildi removed static */
70static IText PortT[]                    = {{"PORT", "Port", 0, 0, 0, 0}};
71ITextVectorProperty PortTP      = { mydev, "DEVICE_PORT", "Ports", COMM_GROUP, IP_RW, 0, IPS_IDLE, PortT, NARRAY(PortT), "", 0};
72
73/**********************************************************************************************/
74/************************************ GROUP: Position Display**********************************/
75/**********************************************************************************************/
76
77/********************************************
78 Property: Equatorial Coordinates JNow
79 Perm: Transient WO.
80 Timeout: 120 seconds.
81*********************************************/
82INumber EquatorialCoordsWN[]            = { {"RA",  "RA  H:M:S", "%10.6m",  0., 24., 0., 0., 0, 0, 0}, {"DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0., 0, 0, 0} };
83INumberVectorProperty EquatorialCoordsWNP= { mydev, "EQUATORIAL_EOD_COORD_REQUEST", "Equatorial JNow", BASIC_GROUP, IP_WO, 120, IPS_IDLE, EquatorialCoordsWN, NARRAY(EquatorialCoordsWN), "", 0};
84
85/********************************************
86 Property: Equatorial Coordinates JNow
87 Perm: RO
88*********************************************/
89INumber EquatorialCoordsRN[]            = { {"RA",  "RA  H:M:S", "%10.6m",  0., 24., 0., 0., 0, 0, 0}, {"DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0., 0, 0, 0}};
90INumberVectorProperty EquatorialCoordsRNP= { mydev, "EQUATORIAL_EOD_COORD", "Equatorial JNow", BASIC_GROUP, IP_RO, 120, IPS_IDLE, EquatorialCoordsRN, NARRAY(EquatorialCoordsRN), "", 0};
91
92
93/*****************************************************************************************************/
94/**************************************** END PROPERTIES *********************************************/
95/*****************************************************************************************************/
96
97/* send client definitions of all properties */
98void ISInit()
99{
100  if (telescope == NULL)
101  {
102    IUSaveText(&PortT[0], "/dev/ttyS0");
103    telescope = new Magellan1();
104    telescope->setCurrentDeviceName(mydev);
105  }
106}
107
108void ISGetProperties (const char *dev)
109{ ISInit(); telescope->ISGetProperties(dev); IEAddTimer (POLLMS, ISPoll, NULL);}
110
111void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
112{ ISInit(); telescope->ISNewSwitch(dev, name, states, names, n);}
113
114void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
115{ ISInit(); telescope->ISNewText(dev, name, texts, names, n);}
116
117void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
118{ ISInit(); telescope->ISNewNumber(dev, name, values, names, n);}
119
120void ISPoll (void *p)
121{ telescope->ISPoll(); IEAddTimer (POLLMS, ISPoll, NULL); p=p;}
122
123void ISNewBLOB (const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
124{
125  INDI_UNUSED(dev);
126  INDI_UNUSED(name);
127  INDI_UNUSED(sizes);
128  INDI_UNUSED(blobsizes);
129  INDI_UNUSED(blobs);
130  INDI_UNUSED(formats);
131  INDI_UNUSED(names);
132  INDI_UNUSED(n);
133}
134
135void ISSnoopDevice (XMLEle *root)
136{
137  telescope->ISSnoopDevice(root);
138}
139
140/**************************************************
141*** MAGELLAN1 Implementation
142***************************************************/
143
144Magellan1::Magellan1()
145{
146   currentSiteNum = 1;
147   trackingMode   = MAGELLAN_TRACK_DEFAULT;
148   lastSet        = -1;
149   fault          = false;
150   simulation     = false;
151   currentSet     = 0;
152   fd             = -1;
153
154   // Children call parent routines, this is the default
155   IDLog("INDI Library v%g\n", INDI_LIBV);
156   IDLog("Initializing from MAGELLAN device...\n");
157   IDLog("Driver Version: 2011-07-28\n");
158}
159
160Magellan1::~Magellan1()
161{
162}
163
164void Magellan1::setCurrentDeviceName(const char * devName)
165{
166  strcpy(thisDevice, devName);
167}
168
169void Magellan1::ISGetProperties(const char *dev)
170{
171
172 if (dev && strcmp (thisDevice, dev))
173    return;
174
175  // COMM_GROUP
176  IDDefSwitch (&ConnectSP, NULL);
177  IDDefText   (&PortTP, NULL);
178
179  // POSITION_GROUP
180  IDDefNumber (&EquatorialCoordsRNP, NULL);
181 
182  /* Send the basic data to the new client if the previous client(s) are already connected. */         
183   if (ConnectSP.s == IPS_OK)
184       getBasicData();
185}
186
187void Magellan1::ISSnoopDevice (XMLEle *root)
188{
189  INDI_UNUSED(root);
190}
191
192void Magellan1::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
193{
194  IText *tp;
195
196  /* Ignore other devices */
197  if (strcmp (dev, thisDevice))
198      return;
199 
200  /* See if the port is updated */
201  if (!strcmp(name, PortTP.name) )
202  {
203    PortTP.s = IPS_OK;
204    tp = IUFindText( &PortTP, names[0] );
205    if (!tp)
206      return;
207
208    IUSaveText(&PortTP.tp[0], texts[0]);
209    IDSetText (&PortTP, NULL);
210    return;
211  }
212}
213
214void Magellan1::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
215{
216  INDI_UNUSED(dev);
217  INDI_UNUSED(name);
218  INDI_UNUSED(values);
219  INDI_UNUSED(names);
220  INDI_UNUSED(n);
221}
222
223void Magellan1::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
224{
225  INDI_UNUSED(names);
226
227  /* Ignore other devices */
228  if (strcmp (thisDevice, dev))
229      return;
230 
231  // FIRST Switch ALWAYS for Connection
232  if (!strcmp (name, ConnectSP.name))
233  {
234    bool connectionEstablished = (ConnectS[0].s == ISS_ON);
235    if (IUUpdateSwitch(&ConnectSP, states, names, n) < 0) return;
236    if ( (connectionEstablished && ConnectS[0].s == ISS_ON) || (!connectionEstablished && ConnectS[1].s == ISS_ON))
237    {
238      ConnectSP.s = IPS_OK;
239      IDSetSwitch(&ConnectSP, NULL);
240      return;
241    }
242    connectTelescope();
243    return;
244  }
245}
246
247void Magellan1::handleError(ISwitchVectorProperty *svp, int err, const char *msg)
248{
249 
250  svp->s = IPS_ALERT;
251 
252    /* First check to see if the telescope is connected */
253    if (check_magellan_connection(fd))
254    {
255      /* The telescope is off locally */
256      ConnectS[0].s = ISS_OFF;
257      ConnectS[1].s = ISS_ON;
258      ConnectSP.s = IPS_BUSY;
259      IDSetSwitch(&ConnectSP, "Telescope is not responding to commands, will retry in 10 seconds.");
260     
261      IDSetSwitch(svp, NULL);
262      IEAddTimer(10000, retryConnection, &fd);
263      return;
264    }
265   
266      /* If the error is a time out, then the device doesn't support this property or busy*/
267      if (err == -2)
268      {
269       svp->s = IPS_ALERT;
270       IDSetSwitch(svp, "Device timed out. Current device may be busy or does not support %s. Will retry again.", msg);
271      }
272      else
273       /* Changing property failed, user should retry. */
274       IDSetSwitch( svp , "%s failed.", msg);
275       
276   fault = true;
277}
278
279void Magellan1::handleError(INumberVectorProperty *nvp, int err, const char *msg)
280{
281 
282  nvp->s = IPS_ALERT;
283 
284  /* First check to see if the telescope is connected */
285    if (check_magellan_connection(fd))
286    {
287      /* The telescope is off locally */
288      ConnectS[0].s = ISS_OFF;
289      ConnectS[1].s = ISS_ON;
290      ConnectSP.s = IPS_BUSY;
291      IDSetSwitch(&ConnectSP, "Telescope is not responding to commands, will retry in 10 seconds.");
292     
293      IDSetNumber(nvp, NULL);
294      IEAddTimer(10000, retryConnection, &fd);
295      return;
296    }
297   
298   /* If the error is a time out, then the device doesn't support this property */
299      if (err == -2)
300      {
301       nvp->s = IPS_ALERT;
302       IDSetNumber(nvp, "Device timed out. Current device may be busy or does not support %s. Will retry again.", msg);
303      }
304      else
305    /* Changing property failed, user should retry. */
306       IDSetNumber( nvp , "%s failed.", msg);
307       
308   fault = true;
309}
310
311void Magellan1::handleError(ITextVectorProperty *tvp, int err, const char *msg)
312{
313 
314tvp->s = IPS_ALERT;
315
316  /* First check to see if the telescope is connected */
317  if (check_magellan_connection(fd))
318  {
319    /* The telescope is off locally */
320    ConnectS[0].s = ISS_OFF;
321    ConnectS[1].s = ISS_ON;
322    ConnectSP.s = IPS_BUSY;
323    IDSetSwitch(&ConnectSP, "Telescope is not responding to commands, will retry in 10 seconds.");
324   
325    IDSetText(tvp, NULL);
326    IEAddTimer(10000, retryConnection, &fd);
327    return;
328  }
329 
330  /* If the error is a time out, then the device doesn't support this property */
331  if (err == -2)
332  {
333      tvp->s = IPS_ALERT;
334      IDSetText(tvp, "Device timed out. Current device may be busy or does not support %s. Will retry again.", msg);
335  }
336     
337  else
338  {
339    /* Changing property failed, user should retry. */
340    IDSetText( tvp , "%s failed.", msg);
341  }
342     
343  fault = true;
344}
345
346 void Magellan1::correctFault()
347 {
348 
349   fault = false;
350   IDMessage(thisDevice, "Telescope is online.");
351   
352 }
353
354bool Magellan1::isTelescopeOn(void)
355{
356  return (ConnectSP.sp[0].s == ISS_ON);
357}
358
359static void retryConnection(void * p)
360{
361  int fd = *( (int *) p);
362 
363  if (check_magellan_connection(fd))
364  {
365    ConnectSP.s = IPS_IDLE;
366    IDSetSwitch(&ConnectSP, "The connection to the telescope is lost.");
367    return;
368  }
369 
370  ConnectS[0].s = ISS_ON;
371  ConnectS[1].s = ISS_OFF;
372  ConnectSP.s = IPS_OK;
373   
374  IDSetSwitch(&ConnectSP, "The connection to the telescope has been resumed.");
375
376}
377
378void Magellan1::ISPoll()
379{
380    int err=0;
381   
382    if (!isTelescopeOn())
383      return;
384
385    if ( (err = getMAGELLANRA(fd, &currentRA)) < 0 || (err = getMAGELLANDEC(fd, &currentDEC)) < 0)
386    {
387      EquatorialCoordsRNP.s = IPS_ALERT;
388      IDSetNumber(&EquatorialCoordsRNP, NULL);
389      handleError(&EquatorialCoordsRNP, err, "Getting RA/DEC");
390      return;
391    }
392   
393    if (fault) correctFault();
394
395    EquatorialCoordsRNP.s = IPS_OK;
396
397    lastRA  = currentRA;
398    lastDEC = currentDEC;
399    IDSetNumber (&EquatorialCoordsRNP, NULL);
400}
401
402void Magellan1::getBasicData()
403{
404  char caldendarDate[10];
405  int err;
406
407  /* Magellan 1 Get Calendar Date As a Test (always 1/1/96) */
408  if ( (err = getCalenderDate(fd, caldendarDate)) < 0)
409     IDMessage(thisDevice, "Failed to retrieve calendar date from device.");
410  else
411     IDMessage(thisDevice, "Successfully retrieved calendar date from device.");
412   
413 
414  /* Only 24 Time format on Magellan and you cant get to the local time
415     which you can set in Magellan I */
416  timeFormat = MAGELLAN_24;
417
418  if ( (err = getMAGELLANRA(fd, &targetRA)) < 0 || (err = getMAGELLANDEC(fd, &targetDEC)) < 0)
419  {
420     EquatorialCoordsRNP.s = IPS_ALERT;
421     IDSetNumber(&EquatorialCoordsRNP, NULL);
422     handleError(&EquatorialCoordsRNP, err, "Getting RA/DEC");
423     return;
424  }
425       
426  if (fault) correctFault();
427
428  EquatorialCoordsRNP.np[0].value = targetRA;
429  EquatorialCoordsRNP.np[1].value = targetDEC;
430 
431  EquatorialCoordsRNP.s = IPS_OK;
432  IDSetNumber (&EquatorialCoordsRNP, NULL); 
433     
434}
435
436void Magellan1::connectTelescope()
437{
438    switch (ConnectSP.sp[0].s)
439    {
440    case ISS_ON: 
441       
442        /* Magellan I only has 1200 buad, 8 data bits, 0 parity and 1 stop bit */
443        if (tty_connect(PortTP.tp[0].text, 1200, 8, 0, 1, &fd) != TTY_OK)
444        {
445          ConnectS[0].s = ISS_OFF;
446          ConnectS[1].s = ISS_ON;
447          IDSetSwitch (&ConnectSP, "Error connecting to port %s. Make sure you have BOTH write and read permission to your port.\n", PortTP.tp[0].text);
448          return;
449        }
450        if (check_magellan_connection(fd))
451        {   
452          ConnectS[0].s = ISS_OFF;
453          ConnectS[1].s = ISS_ON;
454          IDSetSwitch (&ConnectSP, "Error connecting to Telescope. Telescope is offline.");
455          return;
456        }
457
458      #ifdef INDI_DEBUG
459      IDLog("Telescope test successful.\n");
460      #endif
461
462      ConnectSP.s = IPS_OK;
463      IDSetSwitch (&ConnectSP, "Telescope is online. Retrieving basic data...");
464      getBasicData();
465      break;
466
467    case ISS_OFF:
468        ConnectS[0].s = ISS_OFF;
469        ConnectS[1].s = ISS_ON;
470        ConnectSP.s = IPS_IDLE;
471        IDSetSwitch (&ConnectSP, "Telescope is offline.");
472        IDLog("Telescope is offline.");
473        tty_disconnect(fd);
474        break;
475
476  }
477
478}
479
480
481
Note: See TracBrowser for help on using the repository browser.