source: BAORadio/libindi/v1/drivers/telescope/BAO.cpp @ 612

Last change on this file since 612 was 499, checked in by frichard, 14 years ago
  • Messages d'erreur plus explicites
  • Message d'erreur supplémentaire si on suit un objet situé à une altitude inférieure à 30° au-dessus de l'horizon
File size: 45.4 KB
Line 
1  #if 0
2 
3  #############################
4  ##
5  ## BAORadio Indi driver
6  ## Franck RICHARD
7  ## Mai 2010
8  ##
9  #############################
10  #endif
11 
12  #include <stdio.h>
13  #include <stdlib.h>
14  #include <string.h>
15  #include <stdarg.h>
16  #include <math.h>
17  #include <unistd.h>
18  #include <time.h>
19  #include <memory>
20  #include <pthread.h>
21  #include <iostream>
22  #include <time.h>
23  #include <unistd.h>
24  #include <sys/time.h>
25 
26  #include <config.h>
27 
28  #include "indicom.h"
29 
30  #include "Socket.h"
31 
32  #include "BAO.h"
33 
34  using namespace std;
35 
36  auto_ptr<BAO> telescope(0);
37 
38  const int POLLMS = 1;                         // Period of update, 1 ms.
39 
40  const char *mydev = "BAO";                    // Name of our device.
41 
42  const char *BASIC_GROUP    = "Main Control";          // Main Group
43  const char *OPTIONS_GROUP  = "Options";                       // Options Group
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 
51 
52  static void ISPoll(void *);
53 
54  static void retry_connection(void *);
55 
56  /**************************************************************************************
57  **
58  ***************************************************************************************/
59  void *pThreadSocket (void * arg)
60  {
61    try
62    {
63      int pos = SocketsNumber;
64     
65      // Trouver éventuellement un emplacement disponible dans l'intervalle [1..SocketsNumber]
66     
67      /*
68      for (int i=1; i<SocketsNumber; i++)
69      {
70        if (!Sockets[i].Connected)
71        {
72          pos = i;
73          break;
74    }
75    }*/
76     
77      server.accept ( Sockets[pos].new_sock );
78     
79      Sockets[pos].IP=server.recupip(Sockets[pos].new_sock);
80     
81      Sockets[pos].Connected=true;
82     
83      if (pos == SocketsNumber ) SocketsNumber++;
84     
85      InitThreadOK=true;
86    }
87    catch ( SocketException& e )
88    {
89      //A activer pour vérif
90     
91      /*std::string oss;
92      oss="pThreadSocket exception : " + e.description() + "\n";
93      size_t size = oss.size() + 1;
94      char* buffer = new char[size];
95      strncpy(buffer, oss.c_str(), size);
96     
97      IDLog(buffer);
98     
99      delete [] buffer;*/
100    }
101   
102    return NULL;
103  }
104 
105 
106  /**************************************************************************************
107  ** Utilisation d'un thread pour éviter de bloquer l'execution du pilote
108  ** avec la commande accept
109  ***************************************************************************************/
110 
111  void BAO::InitThread()
112  {
113    if (pthread_create (&th1, NULL, pThreadSocket, NULL) < 0)
114    {
115      IDLog("pthread_create error for threadSocket\n");
116    }
117   
118    pthread_join (th1, NULL);
119  }
120 
121  /**************************************************************************************
122  ** Initialisation du pilote BAO
123  ***************************************************************************************/
124  void ISInit()
125  {
126    static int isInit=0;
127   
128    if (isInit) return;
129   
130    if (telescope.get() == 0) telescope.reset(new BAO());
131   
132    isInit = 1;
133   
134    IEAddTimer (POLLMS, ISPoll, NULL);
135  }
136 
137  /**************************************************************************************
138  **
139  ***************************************************************************************/
140  void ISGetProperties (const char *dev)
141  {
142    ISInit();
143    telescope->ISGetProperties(dev);
144  }
145 
146  /**************************************************************************************
147  **
148  ***************************************************************************************/
149  void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
150  {
151    ISInit();
152    telescope->ISNewSwitch(dev, name, states, names, n);
153  }
154 
155  /**************************************************************************************
156  **
157  ***************************************************************************************/
158  void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
159  {
160    ISInit();
161    telescope->ISNewText(dev, name, texts, names, n);
162  }
163 
164  /**************************************************************************************
165  **
166  ***************************************************************************************/
167  void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
168  {
169    ISInit();
170    telescope->ISNewNumber(dev, name, values, names, n);
171  }
172 
173  /**************************************************************************************
174  **
175  ***************************************************************************************/
176  void ISPoll (void *p)
177  {
178    INDI_UNUSED(p);
179   
180    telescope->ISPoll();
181    IEAddTimer (POLLMS, ISPoll, NULL);
182  }
183 
184 
185  /**************************************************************************************
186  **
187  ***************************************************************************************/
188  void ISNewBLOB (const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
189  {
190    INDI_UNUSED(dev);
191    INDI_UNUSED(name);
192    INDI_UNUSED(sizes);
193    INDI_UNUSED(blobsizes);
194    INDI_UNUSED(blobs);
195    INDI_UNUSED(formats);
196    INDI_UNUSED(names);
197    INDI_UNUSED(n);
198  }
199 
200  /**************************************************************************************
201  **
202  ***************************************************************************************/
203  void ISSnoopDevice (XMLEle *root)
204  {
205    INDI_UNUSED(root);
206  }
207 
208  /**************************************************************************************
209  ** Initialisation de la classe BAO
210  ***************************************************************************************/
211  BAO::BAO()
212  {
213    init_properties();
214   
215    ConnectSP.s = IPS_IDLE;
216   
217    lastSet        = -1;
218    fd             = -1;
219    simulation     = false;
220    lastRA         = 0;
221    lastDEC        = 0;
222    currentSet     = 0;
223    JJAnc          = 0.0;
224   
225    SocketsNumber  = 1;
226   
227    ActualisationTM1 = 15.0*60.0;
228   
229    ActualisationTM2 = 5.0;
230   
231    InitThreadOK=false;
232    LecturePosition=false;
233    Abort=false;
234    Park=false;
235    Goto=false;
236    LastGotoOK=true;
237   
238    TrackingMode=1;
239   
240    for (int i=0; i<MAXHOSTNAME; i++)
241    {
242      Sockets[i].Connected=false;
243      Sockets[i].IP="";
244    }
245   
246    InitAntennes();
247   
248   
249    IDLog("Initilizing from BAO device...\n");
250    IDLog("Driver Version: 2010-05-12\n");
251   
252    //enableSimulation(true);
253  }
254 
255  /**************************************************************************************
256  **
257  ***************************************************************************************/
258  BAO::~BAO()
259  {
260   
261  }
262 
263  /**************************************************************************************
264  ** Initialisation des boutons et des zones d'affichage dans la boîte de dialogue INDI
265  ***************************************************************************************/
266  void BAO::init_properties()
267  {
268    // Connection
269    IUFillSwitch(&ConnectS[0], "CONNECT", "Connect", ISS_OFF);
270    IUFillSwitch(&ConnectS[1], "DISCONNECT", "Disconnect", ISS_ON);
271    IUFillSwitchVector(&ConnectSP, ConnectS, NARRAY(ConnectS), mydev, "CONNECTION", "Connection", BASIC_GROUP, IP_RW, ISR_1OFMANY, 60, IPS_IDLE);
272   
273    // Coord Set
274    IUFillSwitch(&OnCoordSetS[0], "TRANSIT", "Transit", ISS_ON);
275    IUFillSwitch(&OnCoordSetS[1], "TRACKING", "Tracking", ISS_OFF);
276    IUFillSwitchVector(&OnCoordSetSP, OnCoordSetS, NARRAY(OnCoordSetS), mydev, "ON_COORD_SET", "On Set", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
277   
278    // Abort
279    IUFillSwitch(&AbortSlewS[0], "ABORT", "Abort", ISS_OFF);
280    IUFillSwitchVector(&AbortSlewSP, AbortSlewS, NARRAY(AbortSlewS), mydev, "ABORT_MOTION", "Abort", BASIC_GROUP, IP_RW, ISR_ATMOST1, 0, IPS_IDLE);
281   
282    // Park
283    IUFillSwitch(&ParkS[0], "PARK", "Park", ISS_OFF);
284    IUFillSwitchVector(&ParkSP, ParkS, NARRAY(ParkS), mydev, "", "Park", BASIC_GROUP, IP_RW, ISR_ATMOST1, 0, IPS_IDLE);
285   
286    // Object Name
287    IUFillText(&ObjectT[0], "OBJECT_NAME", "Name", "--");
288    IUFillTextVector(&ObjectTP, ObjectT, NARRAY(ObjectT), mydev, "OBJECT_INFO", "Object", BASIC_GROUP, IP_RW, 0, IPS_IDLE);
289   
290   
291    // Equatorial Coords - SET
292    IUFillNumber(&EquatorialCoordsWN[0], "RA", "RA  H:M:S", "%10.6m",  0., 24., 0., 0.);
293    IUFillNumber(&EquatorialCoordsWN[1], "DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0.);
294    IUFillNumberVector(&EquatorialCoordsWNP, EquatorialCoordsWN, NARRAY(EquatorialCoordsWN), mydev, "EQUATORIAL_EOD_COORD_REQUEST" , "Equatorial JNow", BASIC_GROUP, IP_WO, 0, IPS_IDLE);
295   
296    // Equatorial Coords - READ
297    //    IUFillNumber(&EquatorialCoordsRN[0], "RA", "RA  H:M:S", "%10.6m",  0., 24., 0., 0.);
298    //    IUFillNumber(&EquatorialCoordsRN[1], "DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0.);
299    //    IUFillNumberVector(&EquatorialCoordsRNP, EquatorialCoordsRN, NARRAY(EquatorialCoordsRN), mydev, "EQUATORIAL_EOD_COORD" , "Equatorial JNow", BASIC_GROUP, IP_RO, 0, IPS_IDLE);
300   
301    // Geographic coord - SET
302    IUFillNumber(&GeographicCoordsWN[0], "LAT", "Lat  D", "%10.6m",  -90., 90., 0., 0.);
303    IUFillNumber(&GeographicCoordsWN[1], "LONG", "Long D", "%10.6m", 0., 360., 0., 0.);
304    IUFillNumberVector(&GeographicCoordsWNP, GeographicCoordsWN, NARRAY(GeographicCoordsWN), mydev, "GEOGRAPHIC_COORD" , "Geographic coords", OPTIONS_GROUP, IP_WO, 0, IPS_IDLE);
305   
306    // Actualisation - SET
307    IUFillNumber(&ActualisationN1[0], "DELAY", "Transit mode delay (Sec)", "%10.6m",  0., 3600., 0., 0.);
308    IUFillNumberVector(&ActualisationNP1, ActualisationN1, NARRAY(ActualisationN1), mydev, "DELAY1" , "", OPTIONS_GROUP, IP_WO, 0, IPS_IDLE);
309   
310    IUFillNumber(&ActualisationN2[0], "DELAY", "Tracking mode delay (Sec)", "%10.6m",  0., 3600., 0., 0.);
311    IUFillNumberVector(&ActualisationNP2, ActualisationN2, NARRAY(ActualisationN2), mydev, "DELAY2" , "", OPTIONS_GROUP, IP_WO, 0, IPS_IDLE);
312   
313    // Transit threshold
314    //IUFillNumber(&SlewAccuracyN[0], "TransitRA",  "RA (arcmin)", "%10.6m",  0., 60., 1., 3.0);
315    //IUFillNumber(&SlewAccuracyN[1], "TransitDEC", "Dec (arcmin)", "%10.6m", 0., 60., 1., 3.0);
316    //IUFillNumberVector(&SlewAccuracyNP, SlewAccuracyN, NARRAY(SlewAccuracyN), mydev, "Transit Accuracy", "", OPTIONS_GROUP, IP_RW, 0, IPS_IDLE);
317   
318    // Tracking threshold
319    //IUFillNumber(&TrackAccuracyN[0], "TrackingRA", "RA (arcmin)", "%10.6m",  0., 60., 1., 3.0);
320    //IUFillNumber(&TrackAccuracyN[1], "TrackingDEC", "Dec (arcmin)", "%10.6m", 0., 60., 1., 3.0);
321    //IUFillNumberVector(&TrackAccuracyNP, TrackAccuracyN, NARRAY(TrackAccuracyN), mydev, "Tracking Accuracy", "", OPTIONS_GROUP, IP_RW, 0, IPS_IDLE);
322   
323  }
324 
325  /**************************************************************************************
326  ** Initialisation de la boîte de dialogue INDI (suite)
327  ***************************************************************************************/
328  void BAO::ISGetProperties(const char *dev)
329  {
330   
331    if (dev && strcmp (mydev, dev))
332      return;
333   
334    // Main Control
335    IDDefSwitch(&ConnectSP, NULL);
336    IDDefText(&ObjectTP, NULL);
337    IDDefNumber(&EquatorialCoordsWNP, NULL);
338    //IDDefNumber(&EquatorialCoordsRNP, NULL);
339    IDDefNumber(&GeographicCoordsWNP, NULL);
340    IDDefSwitch(&OnCoordSetSP, NULL);
341    IDDefSwitch(&AbortSlewSP, NULL);
342    IDDefSwitch(&ParkSP, NULL);
343   
344    // Options
345    //IDDefNumber(&SlewAccuracyNP, NULL);
346    //IDDefNumber(&TrackAccuracyNP, NULL);   
347    IDDefNumber(&ActualisationNP1, NULL);
348    IDDefNumber(&ActualisationNP2, NULL);
349   
350  }
351 
352  /**************************************************************************************
353  ** En cas de changement de texte dans la boîte de dialogue
354  ***************************************************************************************/
355  void BAO::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
356  {
357    // Ignore if not ours
358    if (strcmp (dev, mydev))
359      return;
360   
361    if (is_connected() == false)
362    {
363      IDMessage(mydev, "BAORadio. Please connect before issuing any commands.");
364      reset_all_properties();
365      return;
366    }
367   
368    // ===================================
369    // Object Name
370    // ===================================
371    if (!strcmp (name, ObjectTP.name))
372    {
373      if (IUUpdateText(&ObjectTP, texts, names, n) < 0)
374        return;
375     
376      ObjectTP.s = IPS_OK;
377      IDSetText(&ObjectTP, NULL);
378      return;
379    }
380  }
381 
382  /**************************************************************************************
383  ** En cas de changement d'une valeur numérique dans la boîte de dialogue Indi
384  ***************************************************************************************/
385  void BAO::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
386  {
387   
388    // Ignore if not ours
389    if (strcmp (dev, mydev))
390      return;
391   
392    if (is_connected() == false)
393    {
394      IDMessage(mydev, "BAO is offline. Please connect before issuing any commands.");
395      reset_all_properties();
396      return;
397    }
398   
399   
400    // ===================================
401    // Geographic  Coords
402    // ===================================
403    if (!strcmp (name, GeographicCoordsWNP.name))
404    {
405      int i=0, nset=0, error_code=0;
406     
407      Latitude=0.0;
408      Longitude=0.0;
409     
410      for (nset = i = 0; i < n; i++)
411      {
412        INumber *eqp = IUFindNumber (&GeographicCoordsWNP, names[i]);
413        if (eqp == &GeographicCoordsWN[0])
414        {
415          Latitude = values[i];
416          nset += Latitude >= -90.0 && Latitude <= 90.0;
417         
418          Latitude*=Pidiv180;
419        }
420        else if (eqp == &GeographicCoordsWN[1])
421        {
422          Longitude = values[i];
423          nset += Longitude >= 0.0 && Longitude <= 360.0;
424         
425          Longitude*=-Pidiv180;
426        }
427      }
428     
429      if (nset == 2)
430      {
431        //Vérification
432        //IDLog("Geographic : RA %5.2f - DEC %5.2f\n", Latitude, Longitude);
433       
434        GeographicCoordsWNP.s = IPS_OK;
435        IDSetNumber(&GeographicCoordsWNP, NULL);
436      }
437      else
438      {
439        GeographicCoordsWNP.s = IPS_ALERT;
440        IDSetNumber(&GeographicCoordsWNP, "Latitude or Longitude missing or invalid");
441       
442        Latitude=0.0;
443        Longitude=0.0;
444      }
445     
446      return;
447    }
448   
449   
450    // ===================================
451    // Equatorial Coords
452    // ===================================
453    if (!strcmp (name, EquatorialCoordsWNP.name))
454    {
455      int i=0, nset=0, error_code=0;
456      double newRA =0, newDEC =0;
457     
458      for (nset = i = 0; i < n; i++)
459      {
460        INumber *eqp = IUFindNumber (&EquatorialCoordsWNP, names[i]);
461        if (eqp == &EquatorialCoordsWN[0])
462        {
463          newRA = values[i];     
464          nset += newRA >= 0 && newRA <= 24.0;
465        }
466        else if (eqp == &EquatorialCoordsWN[1])
467        {
468          newDEC = values[i];
469          nset += newDEC >= -90.0 && newDEC <= 90.0;
470        }
471      }
472     
473      targetRA  = newRA;
474      targetDEC = newDEC;
475     
476      if (nset == 2)
477      {
478        char RAStr[32], DecStr[32];
479        double targetAZ, targetAlt;
480       
481        fs_sexa(RAStr, newRA, 2, 3600);
482        fs_sexa(DecStr, newDEC, 2, 3600);
483       
484        IDLog("We received JNow RA %s - DEC %s\n", RAStr, DecStr);
485       
486        // on convertit les coordonnées équatoriales de la zone du ciel observée
487        // en unités de codeurs des moteurs
488       
489        ADDEC2Motor(newRA, newDEC);
490       
491        if (process_coords() == false)
492        {
493          EquatorialCoordsWNP.s = IPS_ALERT;
494          IDSetNumber(&EquatorialCoordsWNP, NULL);
495        }
496      }
497      else
498      {
499        EquatorialCoordsWNP.s = IPS_ALERT;
500        IDSetNumber(&EquatorialCoordsWNP, "RA or Dec missing or invalid");
501      }
502     
503      return;
504    }
505     
506    // ===================================
507    // Actualisation
508    // ===================================
509    if (!strcmp (name, ActualisationNP1.name))
510    {
511      int i=0, nset=0, error_code=0;
512      double newAct1 =0;
513     
514      for (nset = i = 0; i < n; i++)
515      {
516        INumber *eqp = IUFindNumber (&ActualisationNP1, names[i]);
517        if (eqp == &ActualisationN1[0])
518        {
519          newAct1 = values[i];
520         
521          if (newAct1 >= 0.0 && newAct1 <= 3600.0)
522          {
523            ActualisationTM1=newAct1;
524               
525            ActualisationNP1.s = IPS_OK;
526            IDSetNumber(&ActualisationNP1, NULL);
527          }
528          else
529          {
530            ActualisationNP1.s = IPS_ALERT;
531            IDSetNumber(&ActualisationNP1, "Delay invalid");
532          }
533        }
534      }
535     
536    }
537   
538    if (!strcmp (name, ActualisationNP2.name))
539    {
540      int i=0, nset=0, error_code=0;
541      double newAct2 =0;
542     
543      for (nset = i = 0; i < n; i++)
544      {
545        INumber *eqp = IUFindNumber (&ActualisationNP2, names[i]);
546        if (eqp == &ActualisationN2[0])
547        {
548          newAct2 = values[i];
549         
550          if (newAct2 >= 0.0 && newAct2 <= 3600.0)
551          {
552            ActualisationTM2=newAct2;
553               
554            ActualisationNP2.s = IPS_OK;
555            IDSetNumber(&ActualisationNP2, NULL);
556          }
557          else
558          {
559            ActualisationNP2.s = IPS_ALERT;
560            IDSetNumber(&ActualisationNP2, "Delay invalid");
561          }
562        }
563      }
564     
565    } /* end EquatorialCoordsWNP */
566  }
567 
568  /**************************************************************************************
569  ** L'utilisateur clique sur l'un des boutons de la boîte Indi
570  ***************************************************************************************/
571  void BAO::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
572  {
573    // ignore if not ours //
574    if (strcmp (mydev, dev))
575      return;
576   
577    // ===================================
578    // Connect Switch
579    // ===================================
580    if (!strcmp (name, ConnectSP.name))
581    {
582      if (IUUpdateSwitch(&ConnectSP, states, names, n) < 0)
583        return;
584     
585      connect_telescope();
586      return;
587    }
588   
589    if (is_connected() == false)
590    {
591      IDMessage(mydev, "BAORadio is offline. Please connect before issuing any commands.");
592      reset_all_properties();
593      return;
594    }
595   
596    // ===================================
597    // Coordinate Set
598    // ===================================
599    if (!strcmp(name, OnCoordSetSP.name))
600    {
601      if (IUUpdateSwitch(&OnCoordSetSP, states, names, n) < 0)
602        return;
603     
604      currentSet = get_switch_index(&OnCoordSetSP);
605      OnCoordSetSP.s = IPS_OK;
606      IDSetSwitch(&OnCoordSetSP, NULL);
607    }
608   
609    // ===================================
610    // Abort slew
611    // ===================================
612    if (!strcmp (name, AbortSlewSP.name))
613    {
614      Abort=true;
615     
616      IUResetSwitch(&AbortSlewSP);
617     
618      /*
619      if (EquatorialCoordsWNP.s == IPS_BUSY)
620      {
621       
622        AbortSlewSP.s = IPS_OK;
623        EquatorialCoordsWNP.s       = IPS_IDLE;
624        EquatorialCoordsRNP.s       = IPS_IDLE;
625        HorizontalCoordsWNP.s       = IPS_IDLE;
626        IDSetSwitch(&AbortSlewSP, "Slew aborted.");
627        IDSetNumber(&EquatorialCoordsWNP, NULL);
628        IDSetNumber(&EquatorialCoordsRNP, NULL);
629        IDSetNumber(&HorizontalCoordsWNP, NULL);
630    }
631    */
632      return;
633    }
634   
635   
636    // ===================================
637    // Park
638    // ===================================
639    if (!strcmp (name, ParkSP.name))
640    {
641      Park=true;
642     
643      IUResetSwitch(&ParkSP);
644     
645      /*
646      if (EquatorialCoordsWNP.s == IPS_BUSY)
647      {
648       
649        AbortSlewSP.s = IPS_OK;
650        EquatorialCoordsWNP.s       = IPS_IDLE;
651        EquatorialCoordsRNP.s       = IPS_IDLE;
652        HorizontalCoordsWNP.s       = IPS_IDLE;
653        IDSetSwitch(&AbortSlewSP, "Slew aborted.");
654        IDSetNumber(&EquatorialCoordsWNP, NULL);
655        IDSetNumber(&EquatorialCoordsRNP, NULL);
656        IDSetNumber(&HorizontalCoordsWNP, NULL);
657    }
658    */
659      return;
660    }
661  }
662 
663  /**************************************************************************************
664  ** fct peut-être inutile
665  ***************************************************************************************/
666  void BAO::handle_error(INumberVectorProperty *nvp, int err, const char *msg)
667  {
668    nvp->s = IPS_ALERT;
669   
670    /* If the error is a time out, then the device doesn't support this property */
671    if (err == -2)
672    {
673      nvp->s = IPS_ALERT;
674      IDSetNumber(nvp, "Device timed out. Current device may be busy or does not support %s. Will retry again.", msg);
675    }
676    else
677      /* Changing property failed, user should retry. */
678      IDSetNumber( nvp , "%s failed.", msg);
679   
680    fault = true;
681  }
682 
683  /**************************************************************************************
684  ** Initialisation des vecteurs INDI
685  ***************************************************************************************/
686  void BAO::reset_all_properties()
687  {
688    ConnectSP.s                 = IPS_IDLE;
689    OnCoordSetSP.s              = IPS_IDLE;
690    AbortSlewSP.s               = IPS_IDLE;
691    ParkSP.s                    = IPS_IDLE;
692    ObjectTP.s                  = IPS_IDLE;
693    EquatorialCoordsWNP.s       = IPS_IDLE;
694    //EquatorialCoordsRNP.s     = IPS_IDLE;
695    GeographicCoordsWNP.s       = IPS_IDLE;
696    //SlewAccuracyNP.s          = IPS_IDLE;
697    //TrackAccuracyNP.s         = IPS_IDLE;
698    ActualisationNP1.s          = IPS_IDLE;
699    ActualisationNP2.s          = IPS_IDLE;
700   
701    IUResetSwitch(&OnCoordSetSP);
702    IUResetSwitch(&AbortSlewSP);
703    IUResetSwitch(&ParkSP);
704   
705    OnCoordSetS[0].s = ISS_ON;
706    ConnectS[0].s = ISS_OFF;
707    ConnectS[1].s = ISS_ON;
708   
709    IDSetSwitch(&ConnectSP, NULL);
710    IDSetSwitch(&OnCoordSetSP, NULL);
711    IDSetSwitch(&AbortSlewSP, NULL);
712    IDSetSwitch(&ParkSP, NULL);
713    IDSetText(&ObjectTP, NULL);
714    IDSetNumber(&EquatorialCoordsWNP, NULL);
715    //IDSetNumber(&EquatorialCoordsRNP, NULL);
716    IDSetNumber(&GeographicCoordsWNP, NULL);
717    //IDSetNumber(&SlewAccuracyNP, NULL);
718    //IDSetNumber(&TrackAccuracyNP, NULL);
719    IDSetNumber(&ActualisationNP1, NULL);
720    IDSetNumber(&ActualisationNP2, NULL);
721   
722  }
723 
724  /**************************************************************************************
725  **
726  ***************************************************************************************/
727  void BAO::correct_fault()
728  {
729    fault = false;
730    IDMessage(mydev, "Telescope is online.");
731  }
732 
733  /**************************************************************************************
734  **
735  ***************************************************************************************/
736  bool BAO::is_connected()
737  {
738    if (simulation) return true;
739   
740    // return (ConnectSP.sp[0].s == ISS_ON);
741    return (ConnectSP.s == IPS_OK);
742  }
743 
744  /**************************************************************************************
745  **
746  ***************************************************************************************/
747  static void retry_connection(void * p)
748  {
749   
750  }
751 
752 
753  /**************************************************************************************
754  ** Extraction de la position de l'antenne
755  ** dans le retour de la commande POS
756  ** POS/Valeur az/Valeur alt
757  ***************************************************************************************/
758 
759  Position BAO::ExtractPosition(std::string str)
760  {
761    Position result;
762   
763    std::string str2;
764   
765    result.x = -1;
766    result.y = -1;
767   
768    int pos = str.find("/");
769   
770    if (pos != string::npos)
771    {
772      str2 = str.substr(pos+1);
773     
774      pos = str2.find("/");
775     
776      if (pos != string::npos)
777      {
778        result.x = atoi(str2.substr(0, pos).c_str());
779       
780        result.y = atoi(str2.substr(pos+1).c_str());
781      }
782    }
783   
784    return result;
785  }
786 
787 
788 
789  /************************************************************************************
790  * cette procédure convertit les coordonnées equatoriales de l'objet visé
791  * en unités de codeurs des paraboles (nb de tours des deux axes moteurs depuis la position PARK)
792  ************************************************************************************/
793  void BAO::ADDEC2Motor(double newRA, double newDEC)
794  {
795    double targetAz;
796    double targetAlt;
797    char AzStr[32];
798    char AltStr[32];
799   
800    // Calcule la hauteur et l'azimut de la zone du ciel pointée (en fonction de la date et du lieu)
801   
802    Azimut(tsl, Latitude, newRA * 15.0 * Pidiv180, newDEC * Pidiv180, &targetAz, &targetAlt);
803   
804    // En degrés
805   
806    targetAlt *= N180divPi;
807    targetAz *= N180divPi;
808   
809    // Affichage dans les logs
810   
811    fs_sexa(AzStr, targetAz, 2, 3600);
812    fs_sexa(AltStr, targetAlt, 2, 3600);
813   
814    IDLog("Horizontal coords : az %s - Alt %s\n", AzStr, AltStr);
815   
816    // Le calcul est ici trÚs sommaire et arbitraire :
817    // Je considÚre qu'il y a 100 positions possibles sur les deux axes
818    // De plus, je considÚre qu'il n'est pas possible de viser un objet à
819    // moins de 30° de hauteur au-dessus de l'horizon
820   
821    TargetPosition.x=(int)(targetAz*100.0/360.0);
822   
823    targetAlt=((90.0-targetAlt)/60.0);
824   
825    if (targetAlt>=1.0) 
826    {
827          targetAlt=1.0; //on ne peut pas viser un objet situé à moins de 30°
828          //au-dessus de l'horizon
829         
830          IDSetSwitch(&OnCoordSetSP, "Erreur : l objet suivi est situé à moins de 30° en-dessus de l horizon. Goto annulé.");
831         
832          Goto=false;
833         
834          LecturePosition=false;
835       
836          InitAntennes();
837    }
838 
839    TargetPosition.y=(int)(100.0*targetAlt);
840  }
841 
842 
843  /************************************************************************************
844  * Retourne simplement le nombre d'antennes connectées
845  * et capables de communiquer
846  ************************************************************************************/
847 
848  int BAO::AntennesConnectees()
849  {
850    int num=0;
851   
852    for (int i=1; i<SocketsNumber; i++) if (Sockets[i].Connected) num++;
853   
854    return num;
855  }
856 
857 
858  /************************************************************************************
859  * Initialisation des paramÚtres des antennes
860  *
861  ************************************************************************************/
862  void BAO::InitAntennes()
863  {
864    for (int i=0; i < MAXHOSTNAME ; i++)
865    {
866      Sockets[i].status=0;
867      Sockets[i].sendalertes=0;
868      Sockets[i].AttenteExecution=0;
869      Sockets[i].AnomaliesExecution=0;
870      Sockets[i].etape=0;
871     
872      Sockets[i].ack_status=false;
873      Sockets[i].ack_pos=false;
874      Sockets[i].ack_park=false;
875      Sockets[i].ack_abort=false;
876      Sockets[i].ack_goto=false;
877     
878      Sockets[i].PosValides=false;
879      Sockets[i].GotoOk=false;
880    }
881  }
882 
883 
884  /**************************************************************************************
885  ** Procédure principale
886  ** Elle est appelée toutes les POLLMS ms (ici 1 ms)
887  ***************************************************************************************/
888  void BAO::ISPoll()
889  {
890    static bool ISPOLLRunning=false;
891    static int memSocketsNumber=-1;
892    static unsigned int compt=100;
893   
894    int pos;
895   
896    struct tm date;
897    time_t t;
898    struct timeval tv;
899    struct timezone tz;
900   
901    if (is_connected() == false) return;
902   
903    if (ISPOLLRunning) return;
904   
905    ISPOLLRunning=true;
906   
907    compt++;
908   
909   
910    //toutes les 100 millisec
911   
912    if ( compt%100 == 0)
913    {
914      //Récupération de la date et de l'heure
915     
916      time(&t);
917      date=*gmtime(&t);
918      gettimeofday(&tv, &tz);
919     
920      Annee=(double)(date.tm_year+1900);
921      Mois=(double)(date.tm_mon+1);
922      Jour=(double)date.tm_mday;
923      Heu=(double)date.tm_hour;
924      Min=(double)date.tm_min;
925      Sec=(double)date.tm_sec+tv.tv_usec/1.0E6;
926      UTCP=0.0;//(double)date.tm_isdst;
927     
928     
929      //Calcul du temps sidéral local
930     
931      CalculTSL();
932     
933     
934      //Y a-t-il de nouvelles tentatives de connexion sur le serveur ?
935     
936      InitThread();         
937    }
938   
939   
940   
941   
942    if (InitThreadOK)  // Il faut qu'il y ait eu au moins une connexion détectée par le thread pour continuer
943    {
944     
945      // Nouvelle connexion sur le socket !
946     
947      if (SocketsNumber>memSocketsNumber)
948      {
949        memSocketsNumber=SocketsNumber;
950       
951        IDSetSwitch(&ConnectSP, "Connexion de l antenne %s. (Antennes connectées : %i)",
952                    Sockets[SocketsNumber-1].IP.c_str(), AntennesConnectees());
953      }
954     
955     
956     
957      // Début des échanges avec les microcontrÃŽleurs
958     
959      // Analyse des réponses des microcontrÃŽleurs
960     
961      for (int i=1; i<SocketsNumber; i++) /*if (Sockets[i].Connected)*/
962      {
963        try
964        {
965          std::string reponse, memreponse;
966          // on récupÚre la réponse du microcontrÃŽleur
967         
968          Sockets[i].new_sock >> reponse;
969         
970          //IDSetSwitch(&OnCoordSetSP, "Réponse ISPOLL : %s\n", reponse.c_str());        // pour vérif
971         
972          //Dans le cas où plusieurs trames seraient arrivées entre deux appels de POLLMS
973          //les traiter successivement
974         
975          pos=reponse.find("\n");   // d'où l'intérêt de mettre un '\n' à la fin des trames
976          //pour différencier une trame de la précédente
977          while ((pos!=string::npos) && (reponse.length()>1))
978          {
979            memreponse=reponse.substr(pos+1);
980           
981            reponse=reponse.substr(0, pos);
982           
983           
984            // On traite ici les acknowledges
985           
986            if ((reponse.find("ACK")!=string::npos) && (reponse.find("NACK")==string::npos))
987            {         
988              if (reponse.find("POS")!=string::npos)
989              {
990                Sockets[i].ack_pos=true;
991              }
992              else if (reponse.find("GOTO")!=string::npos)
993              {
994                Sockets[i].ack_goto=true;
995              }
996              else if (reponse.find("PARK")!=string::npos)
997              {
998                Sockets[i].ack_park=true;
999              }
1000              else if (reponse.find("ABORT")!=string::npos)
1001              {
1002                Sockets[i].ack_abort=true;
1003              }
1004            }
1005            else
1006            {
1007             
1008              //réponse à la requête POSITION
1009              if (reponse.find("POS")!=string::npos)
1010              {
1011                if (reponse.find("NACK")!=string::npos)
1012                {
1013                  OnCoordSetSP.s = IPS_ALERT;
1014                  IDSetSwitch(&OnCoordSetSP, "ALERTE antenne %s : position de l antenne inconnue !\n",
1015                              Sockets[i].IP.c_str());
1016                              Sockets[i].PosValides=false;
1017                              // Si la position de l'antenne est inconnue, on déconnecte l'antenne
1018                              Sockets[i].Connected=false;
1019                }
1020                else if (Sockets[i].ack_pos)
1021                {
1022                  OnCoordSetSP.s = IPS_OK;
1023                  Sockets[i].Pos = ExtractPosition(reponse);
1024                  Sockets[i].PosValides = true;
1025                  IDSetSwitch(&ParkSP, "Antenne %s : POSITION OK  (x=%i, y=%i)\n",
1026                    Sockets[i].IP.c_str(), Sockets[i].Pos.x, Sockets[i].Pos.y);
1027                }
1028               
1029              }//réponse à la requête PARK
1030              else if (reponse.find("PARK")!=string::npos)
1031              {
1032                if (reponse.find("NACK")!=string::npos)
1033                {
1034                  ParkSP.s = IPS_ALERT;
1035                  IDSetSwitch(&ParkSP, "ALERTE antenne %s : erreur PARK !\n", Sockets[i].IP.c_str());
1036                } 
1037                else if (reponse.find("OK")!=string::npos)
1038                {
1039                  ParkSP.s = IPS_OK;
1040                  IDSetSwitch(&ParkSP, "Antenne %s : PARK OK\n",  Sockets[i].IP.c_str());
1041                }
1042               
1043              }//réponse à la requête ABORT
1044              else if (reponse.find("ABORT")!=string::npos)
1045              {
1046                if (reponse.find("NACK")!=string::npos)
1047                {
1048                  AbortSlewSP.s = IPS_ALERT;
1049                  IDSetSwitch(&AbortSlewSP, "ALERTE antenne %s : erreur ABORT !\n",  Sockets[i].IP.c_str());
1050                }
1051               
1052                if (reponse.find("OK")!=string::npos)
1053                {
1054                  AbortSlewSP.s = IPS_OK;
1055                  IDSetSwitch(&AbortSlewSP, "Antenne %s : ABORT OK\n",  Sockets[i].IP.c_str());
1056                }
1057               
1058              } //réponse à la requête GOTO
1059              else if (reponse.find("GOTO")!=string::npos)
1060              {
1061                if (reponse.find("NACK")!=string::npos)
1062                {
1063                  OnCoordSetSP.s = IPS_ALERT;
1064                  IDSetSwitch(&OnCoordSetSP, "ALERTE antenne %s : Erreur GOTO !\n",  Sockets[i].IP.c_str());
1065                  Sockets[i].Connected=false;
1066                }
1067                else if (Sockets[i].ack_goto)
1068                {
1069                  if (reponse.find("OK")!=string::npos)
1070                  {
1071                    OnCoordSetSP.s = IPS_OK;
1072                 
1073                    Sockets[i].GotoOk=true;
1074                 
1075                    IDSetSwitch(&ParkSP, "Antenne %s : GOTO OK.\n",  Sockets[i].IP.c_str());
1076                 
1077                    lastRA  = targetRA;
1078                    lastDEC = targetDEC;
1079                 
1080                     //IDLog("We received JNow RA %s - DEC %s\n", RAStr, DecStr);*/
1081                 
1082                    EquatorialCoordsWNP.s = IPS_OK;
1083                    IDSetNumber (&EquatorialCoordsWNP, NULL);
1084                 
1085                    // Fin du Goto pour toutes les antennes ?
1086                 
1087                    int num=0;
1088                 
1089                    for (int j=1; j<SocketsNumber; j++) if (Sockets[j].Connected)
1090                    {
1091                      if (Sockets[j].GotoOk) num++;
1092                    }
1093                 
1094                    if ((num == AntennesConnectees()) && (num>0))
1095                    {
1096                      LecturePosition=false;
1097                   
1098                      InitAntennes();
1099                     
1100                      LastGotoOK=true;
1101                   
1102                      IDSetSwitch(&OnCoordSetSP, "GOTO OK !");
1103                    }
1104                  } 
1105                }
1106              }
1107            }
1108           
1109            // On passe éventuellement à la trame suivante
1110           
1111            reponse=memreponse;
1112            pos=reponse.find("\n");
1113           
1114          }
1115        }
1116        catch (SocketException& e) //Aïe
1117        {
1118          Sockets[i].new_sock.shutdown();
1119          Sockets[i].new_sock.create();
1120          Sockets[i].Connected = Sockets[i].new_sock.connect((std::string)Sockets[i].IP);
1121         
1122          if (Sockets[i].Connected)
1123          {
1124            Sockets[i].AttenteExecution=0;
1125            Sockets[i].AnomaliesExecution=0;
1126          } 
1127         
1128          std::string oss;
1129          oss="SocketException IsPoll : " + e.description() + "\n";
1130          size_t size = oss.size() + 1;
1131          char* buffer = new char[size];
1132          strncpy(buffer, oss.c_str(), size);
1133          IDLog(buffer);
1134          delete [] buffer;
1135        }
1136      }
1137     
1138     
1139     
1140      if (Abort)
1141      {
1142        IDSetSwitch(&ConnectSP, "Envoi de la commande Abort\n");
1143       
1144        Goto=false;
1145       
1146        for (int i=1; i<SocketsNumber; i++) if (Sockets[i].Connected)
1147        {
1148          if (!ABORT(i)) Sockets[i].sendalertes++;
1149        }
1150       
1151        LecturePosition=false;
1152       
1153        InitAntennes();
1154       
1155        Abort=false;
1156      }
1157     
1158     
1159      if (Park)
1160      {
1161        IDSetSwitch(&ConnectSP, "Envoi de la commande Park\n");
1162       
1163        Goto=false;
1164       
1165        for (int i=1; i<SocketsNumber; i++) if (Sockets[i].Connected)
1166        {
1167          if (!PARK(i)) Sockets[i].sendalertes++;
1168        }
1169       
1170        LecturePosition=false;
1171       
1172        InitAntennes();
1173       
1174        Park=false;
1175      }
1176     
1177     
1178      // Gestion du suivi
1179     
1180      if ((Goto) && (LastGotoOK))
1181      {
1182        // Durée entre deux actualisations
1183       
1184        double delai=ActualisationTM1/3600.0/24.0;   // Actualisation toutes les 15 minutes en mode transit
1185       
1186        if (TrackingMode==2) delai=ActualisationTM2/3600.0/24.0;   //et 5 secs en mode tracking
1187         
1188         
1189          // On actualise la position
1190         
1191          if (JJ-JJAnc > delai)
1192          {
1193           
1194            LastGotoOK=false;
1195           
1196            LecturePosition=true;
1197           
1198            ADDEC2Motor(targetRA, targetDEC);
1199           
1200            InitAntennes();         
1201           
1202            JJAnc=JJ;
1203          }
1204         
1205          //Plus d'antenne !
1206         
1207          if (AntennesConnectees() == 0)
1208          {
1209            // LecturePosition=false;
1210           
1211            // Goto=false;
1212           
1213            // InitAntennes();
1214           
1215            if ( compt % 1000 == 0)  IDSetSwitch(&OnCoordSetSP, "Erreur ! Plus d antennes connectées !");
1216          }
1217      }
1218     
1219     
1220     
1221      // Exécution de la procédure complÚte de lecture de la position de l'antenne
1222      // puis envoi d'une commande Goto
1223     
1224      if (LecturePosition)
1225      {
1226        for (int i=1; i<SocketsNumber; i++) /*if (Sockets[i].Connected)*/
1227        {
1228          switch (Sockets[i].etape)
1229          {
1230           
1231            //Envoi de la commande POS
1232            case 0 :
1233            {
1234              Sockets[i].ack_pos=false;
1235              Sockets[i].PosValides=false;
1236             
1237              if (!POSITION(i)) Sockets[i].sendalertes++;
1238             
1239              Sockets[i].etape++;
1240            }
1241            break;
1242           
1243            //ack POS
1244            case 1 :
1245            {
1246              if (Sockets[i].ack_pos)
1247              {
1248                Sockets[i].AttenteExecution=0;
1249                Sockets[i].AnomaliesExecution=0;
1250                Sockets[i].etape++;
1251                i--;
1252              }
1253              else
1254              {
1255                // on réitÚre l'ordre précédent si rien ne se passe
1256               
1257                Sockets[i].AttenteExecution++;
1258               
1259                if (Sockets[i].AttenteExecution>MAXATTENTE)
1260                {
1261                  Sockets[i].etape=0;
1262                  Sockets[i].AttenteExecution=0;
1263                  Sockets[i].AnomaliesExecution++;
1264                }
1265               
1266                if (Sockets[i].AnomaliesExecution>MAXANOMALIES)
1267                {
1268                  Sockets[i].etape=3;
1269                 
1270                 // if ( compt % 1000 == 0)
1271                  {
1272                    IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s. Pas d acknowledge reçu aprÚs l ordre POSITION. Déconnexion de l antenne.",
1273                                Sockets[i].IP.c_str());
1274                                Sockets[i].Connected=false;
1275                  }
1276                }
1277              }
1278            }
1279            break;
1280           
1281            //Valeurs pos valides ?
1282            case 2 :
1283            {
1284              if (Sockets[i].PosValides)
1285              {
1286                Sockets[i].AttenteExecution=0;
1287                Sockets[i].etape++;
1288              }
1289              else
1290              {
1291                // on réitÚre l'ordre précédent si rien ne se passe
1292               
1293                Sockets[i].AttenteExecution++;
1294               
1295                if (Sockets[i].AttenteExecution>MAXATTENTE)
1296                {
1297                  Sockets[i].etape=2;
1298                  Sockets[i].AttenteExecution=0;
1299                  Sockets[i].AnomaliesExecution++;
1300                }
1301               
1302                if (Sockets[i].AnomaliesExecution>MAXANOMALIES)
1303                {
1304                  Sockets[i].etape=3;
1305                 
1306                 // if ( compt % 1000 == 0)
1307                  {
1308                    IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s. La position retournée n est pas valide. Déconnexion de l antenne.",
1309                                Sockets[i].IP.c_str());
1310                                Sockets[i].Connected=false;
1311                  }
1312                }
1313              }
1314            }
1315            break;
1316           
1317            //ack goto  ?
1318            case 4 :
1319            {
1320              if (Sockets[i].ack_goto)
1321              {
1322                Sockets[i].AttenteExecution=0;
1323                Sockets[i].AnomaliesExecution=0;
1324                Sockets[i].etape++;
1325              }
1326              else
1327              {
1328                // on réitÚre l'ordre précédent si rien ne se passe
1329               
1330                Sockets[i].AttenteExecution++;
1331               
1332                if (Sockets[i].AttenteExecution>MAXATTENTE)
1333                {
1334                  Sockets[i].etape=4;
1335                  Sockets[i].AttenteExecution=0;
1336                  Sockets[i].AnomaliesExecution++;
1337                }
1338               
1339                if (Sockets[i].AnomaliesExecution>MAXANOMALIES)
1340                {
1341                  Sockets[i].etape=6;
1342                 
1343                 // if ( compt % 1000 == 0)
1344                  {
1345                    IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s. Pas d acknowledge reçu aprÚs l ordre GOTO. Déconnexion de l antenne.",
1346                                Sockets[i].IP.c_str());
1347                                Sockets[i].Connected=false;
1348                  }
1349                }
1350              }
1351            }
1352            break;
1353           
1354            //goto ok  ?
1355            case 5 :
1356            {
1357              if (Sockets[i].GotoOk)
1358              {
1359                Sockets[i].AttenteExecution=0;
1360                Sockets[i].AnomaliesExecution=0;
1361                Sockets[i].etape++;
1362              }
1363              else
1364              {
1365                // on réitÚre l'ordre précédent si rien ne se passe
1366               
1367                Sockets[i].AttenteExecution++;
1368               
1369                if (Sockets[i].AttenteExecution>MAXATTENTE)
1370                {
1371                  Sockets[i].etape=5;
1372                  Sockets[i].AttenteExecution=0;
1373                  Sockets[i].AnomaliesExecution++;
1374                }
1375               
1376                if (Sockets[i].AnomaliesExecution>MAXANOMALIESGOTO)
1377                {
1378                  Sockets[i].etape=6;
1379                 
1380                 // if ( compt % 1000 == 0)
1381                  {
1382                    IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s. L antenne n a pas renvoyé GOTO/OK. Déconnexion de l antenne.",
1383                                Sockets[i].IP.c_str());
1384                                Sockets[i].Connected=false;
1385                               
1386                               
1387                  }
1388                }
1389              }
1390            }
1391            break;
1392           
1393          }
1394        }
1395      }
1396     
1397     
1398     
1399     
1400     
1401     
1402      // Détection d'anomalies concernant l'envoi de trames sur la socket. déconnexion du micro-cont ?
1403     
1404      for (int i=1; i<SocketsNumber; i++) if (Sockets[i].Connected)
1405      {
1406        if (Sockets[i].sendalertes > 0)
1407        {
1408          Sockets[i].etape=5;
1409         
1410        //  if ( compt % 1000 == 0)
1411          {
1412            IDSetSwitch(&OnCoordSetSP, "Anomalie détectée sur l antenne %s. Déconnexion de l antenne.",
1413                        Sockets[i].IP.c_str());
1414                       
1415                        Sockets[i].Connected=false;
1416          }
1417        }
1418      }
1419     
1420     
1421     
1422      //On attend que toutes les antennes soient prêtes pour lancer l'ordre Goto -> meilleure synchronisation
1423     
1424      int num=0;
1425     
1426      for (int i=1; i<SocketsNumber; i++) if (Sockets[i].Connected)
1427      {
1428        if (Sockets[i].etape == 3) num++; //fin de la procédure LecturePosition. Les antennes sont prêtes
1429          //à recevoir l'ordre GOto
1430      }
1431     
1432      if ((num == AntennesConnectees()) && (num>0))
1433      {
1434        for (int i=1; i<SocketsNumber; i++ ) if (Sockets[i].Connected)
1435        {
1436          Sockets[i].ack_goto=false;
1437          Sockets[i].AttenteExecution=0;
1438          Sockets[i].AnomaliesExecution=0;
1439         
1440          if (!GOTO(i, Sockets[i].Pos.x - TargetPosition.x, Sockets[i].Pos.y - TargetPosition.y )) Sockets[i].sendalertes++;
1441         
1442          Sockets[i].etape++;
1443        }
1444      }
1445     
1446     
1447       
1448    }
1449   
1450    ISPOLLRunning=false;
1451  }
1452 
1453 
1454 
1455  /**************************************************************************************
1456  **
1457  ***************************************************************************************/
1458  bool BAO::process_coords()
1459  {
1460    switch (currentSet)
1461    {
1462      // Transit
1463      case BAO_TRANSIT:
1464       
1465        EquatorialCoordsWNP.s = IPS_BUSY;
1466       
1467        IDSetNumber (&EquatorialCoordsWNP, NULL);
1468       
1469        InitAntennes();
1470       
1471        JJAnc=JJ;
1472       
1473        TrackingMode = 1;
1474       
1475        Goto=true;
1476       
1477        LastGotoOK=false;
1478       
1479        LecturePosition=true;
1480       
1481        ADDEC2Motor(targetRA, targetDEC);
1482       
1483        break;
1484       
1485        // Tracking
1486      case BAO_TRACKING:
1487       
1488        EquatorialCoordsWNP.s = IPS_BUSY;
1489       
1490        IDSetNumber (&EquatorialCoordsWNP, NULL);
1491       
1492        InitAntennes();
1493       
1494        JJAnc=JJ;
1495       
1496        TrackingMode = 2;
1497       
1498        Goto=true;
1499       
1500        LastGotoOK=false;
1501       
1502        LecturePosition=true;
1503       
1504        ADDEC2Motor(targetRA, targetDEC);
1505       
1506        break;
1507    }
1508   
1509    return true;
1510  }
1511 
1512  /**************************************************************************************
1513  **
1514  ***************************************************************************************/
1515  int BAO::get_switch_index(ISwitchVectorProperty *sp)
1516  {
1517    for (int i=0; i < sp->nsp ; i++)
1518      if (sp->sp[i].s == ISS_ON)
1519        return i;
1520     
1521      return -1;
1522  }
1523 
1524  /**************************************************************************************
1525  ** Activation de l'interface
1526  ***************************************************************************************/
1527  void BAO::connect_telescope()
1528  {
1529    switch (ConnectSP.sp[0].s)
1530    {
1531      case ISS_ON:
1532        ConnectS[0].s = ISS_ON;
1533        ConnectS[1].s = ISS_OFF;
1534        IDLog("\nHello BAORadio !\n");
1535       
1536        ConnectSP.s = IPS_OK;
1537        IDSetSwitch (&ConnectSP, "BAORadio is online. Retrieving basic data...");
1538       
1539       
1540        break;
1541       
1542      case ISS_OFF:
1543        ConnectS[0].s = ISS_OFF;
1544        ConnectS[1].s = ISS_ON;
1545        ConnectSP.s = IPS_IDLE;
1546       
1547        SocketsNumber=1;
1548        InitThreadOK=false;
1549       
1550        for (int i=0; i<MAXHOSTNAME; i++)
1551        {
1552          Sockets[i].Connected=false;
1553          Sockets[i].IP="";
1554          Sockets[i].new_sock.shutdown();
1555        }
1556       
1557        InitAntennes();
1558       
1559        IDSetSwitch (&ConnectSP, "BAORadio is offline.");
1560        IDLog("Telescope is offline.");
1561       
1562        break;
1563    }
1564  }
1565 
1566  /**************************************************************************************
1567  **
1568  ***************************************************************************************/
1569  void BAO::get_initial_data()
1570  {
1571    //  IDSetNumber (&EquatorialCoordsRNP, NULL);
1572   
1573     
1574  }
1575 
1576  /**************************************************************************************
1577  **
1578  ***************************************************************************************/
1579  void BAO::slew_error(int slewCode)
1580  {
1581    OnCoordSetSP.s = IPS_IDLE;
1582   
1583    if (slewCode == 1)
1584      IDSetSwitch (&OnCoordSetSP, "Object below horizon.");
1585    else if (slewCode == 2)
1586      IDSetSwitch (&OnCoordSetSP, "Object below the minimum elevation limit.");
1587    else
1588      IDSetSwitch (&OnCoordSetSP, "Slew failed.");
1589  }
1590 
1591  /**************************************************************************************
1592  **
1593  ***************************************************************************************/
1594  void BAO::enable_simulation(bool enable)
1595  {
1596    simulation = enable;
1597   
1598    if (simulation)
1599      IDLog("Warning: Simulation is activated.\n");
1600    else
1601      IDLog("Simulation is disabled.\n");
1602  }
1603 
1604  /**************************************************************************************
1605  **
1606  ***************************************************************************************/
1607  void BAO::connection_lost()
1608  {
1609    ConnectSP.s = IPS_IDLE;
1610    IDSetSwitch(&ConnectSP, "The connection to the telescope is lost.");
1611    return;
1612  }
1613 
1614  /**************************************************************************************
1615  **
1616  ***************************************************************************************/
1617  void BAO::connection_resumed()
1618  {
1619    ConnectS[0].s = ISS_ON;
1620    ConnectS[1].s = ISS_OFF;
1621    ConnectSP.s = IPS_OK;
1622   
1623    IDSetSwitch(&ConnectSP, "The connection to the telescope has been resumed.");
1624  }
1625 
1626 
1627  /**************************************************************************************
1628  **  Envoi d'une commande sur le socket puis attente de l'acknowledge
1629  ***************************************************************************************/
1630 
1631  bool BAO::COMMANDE(int numsocket, char* Commande, char* Params)
1632  {
1633    char chaine[MAXCARACTERES];
1634   
1635    try
1636    {
1637      sprintf(chaine, "%s%s\n", Commande, Params);
1638     
1639      Sockets[numsocket].new_sock << chaine;
1640    }
1641    catch (SocketException& e)
1642    {       
1643      Sockets[numsocket].new_sock.shutdown();
1644      Sockets[numsocket].new_sock.create();
1645      Sockets[numsocket].Connected = Sockets[numsocket].new_sock.connect((std::string)Sockets[numsocket].IP);
1646     
1647      if (Sockets[numsocket].Connected)
1648      {
1649        Sockets[numsocket].AttenteExecution=0;
1650        Sockets[numsocket].AnomaliesExecution=0;
1651      }
1652     
1653      //  if (AntennesConnectees() == 0) { InitAntennes(); InitThreadOK=false;}
1654     
1655      std::string oss;
1656      oss="COMMANDE exception : " + e.description() + "\n";
1657      size_t size = oss.size() + 1;
1658      char* buffer = new char[size];
1659      strncpy(buffer, oss.c_str(), size);
1660     
1661      IDLog(buffer);
1662     
1663      delete [] buffer;
1664     
1665      return false;
1666    }
1667   
1668    return true;
1669  }
1670 
1671 
1672  /**************************************************************************************
1673  ** Commande POSITION
1674  ***************************************************************************************/
1675 
1676  bool BAO::POSITION(int numsocket)
1677  {
1678    return COMMANDE(numsocket, (char*)"P", (char*)"");
1679  }
1680 
1681  /**************************************************************************************
1682  ** Commande PARK
1683  ***************************************************************************************/
1684 
1685  bool BAO::PARK(int numsocket)
1686  {
1687    return COMMANDE(numsocket, (char*)"Z", (char*)"");
1688  }
1689 
1690  /**************************************************************************************
1691  ** Commande ABORT
1692  ***************************************************************************************/
1693 
1694  bool BAO::ABORT(int numsocket)
1695  {
1696    return COMMANDE(numsocket, (char*)"A", (char*)"");
1697  }
1698 
1699 
1700  /**************************************************************************************
1701  ** Commande GOTO
1702  ***************************************************************************************/
1703 
1704  bool BAO::GOTO(int numsocket, int deltaAz, int deltaAlt)
1705  {
1706    char Params[MAXCARACTERES];
1707    char sensAz;
1708    char sensAlt;
1709   
1710    sensAlt='b';
1711    sensAz='b';
1712   
1713    if (deltaAz<0)
1714    {
1715      deltaAz=-deltaAz;
1716      sensAz='f';
1717    }
1718   
1719    if (deltaAlt<0)
1720    {
1721      deltaAlt=-deltaAlt;
1722      sensAlt='f';
1723    }
1724   
1725    sprintf(Params, "%c%04i%c%04i", sensAz, deltaAz, sensAlt, deltaAlt);
1726   
1727    return COMMANDE(numsocket, (char*)"G", Params);
1728  }
1729 
1730 
1731 
Note: See TracBrowser for help on using the repository browser.