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

Last change on this file since 620 was 501, checked in by frichard, 14 years ago

-BAOControl : petite interface permettant de contrôler les antennes via le pilote indi_BAO
-Le pilote indi_BAO utilise désormais libindi v 0.7

File size: 51.6 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
34using namespace std;
35
36auto_ptr<BAO> telescope(0);
37
38const int POLLMS = 1;                           // Period of update, 1 ms.
39
40const char *mydev = "BAO";                      // Name of our device.
41
42const char *BASIC_GROUP    = "Main Control";            // Main Group
43const 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
52static void ISPoll(void *);
53
54static void retry_connection(void *);
55
56/**************************************************************************************
57**
58***************************************************************************************/
59void *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
111void 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***************************************************************************************/
124void 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***************************************************************************************/
140void ISGetProperties (const char *dev)
141{
142    ISInit();
143    telescope->ISGetProperties(dev);
144}
145
146/**************************************************************************************
147**
148***************************************************************************************/
149void 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***************************************************************************************/
158void 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***************************************************************************************/
167void 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***************************************************************************************/
176void ISPoll (void *p)
177{
178    INDI_UNUSED(p);
179
180    telescope->ISPoll();
181    IEAddTimer (POLLMS, ISPoll, NULL);
182}
183
184
185/**************************************************************************************
186**
187***************************************************************************************/
188void 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***************************************************************************************/
203void ISSnoopDevice (XMLEle *root)
204{
205    INDI_UNUSED(root);
206}
207
208/**************************************************************************************
209** Initialisation de la classe BAO
210***************************************************************************************/
211BAO::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-11-10\n");
251
252    //enableSimulation(true);
253}
254
255/**************************************************************************************
256**
257***************************************************************************************/
258BAO::~BAO()
259{
260
261}
262
263/**************************************************************************************
264** Initialisation des boutons et des zones d'affichage dans la boîte de dialogue INDI
265***************************************************************************************/
266void 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***************************************************************************************/
328void 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***************************************************************************************/
355void 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, "Error ! 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***************************************************************************************/
385void 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, "Error ! 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, "Error ! 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, "Error ! Delay invalid");
532                }
533            }
534        }
535    }
536
537    if (!strcmp (name, ActualisationNP2.name))
538    {
539        int i=0, nset=0, error_code=0;
540        double newAct2 =0;
541
542        for (nset = i = 0; i < n; i++)
543        {
544            INumber *eqp = IUFindNumber (&ActualisationNP2, names[i]);
545            if (eqp == &ActualisationN2[0])
546            {
547                newAct2 = values[i];
548
549                if (newAct2 >= 0.0 && newAct2 <= 3600.0)
550                {
551                    ActualisationTM2=newAct2;
552
553                    ActualisationNP2.s = IPS_OK;
554                    IDSetNumber(&ActualisationNP2, NULL);
555                }
556                else
557                {
558                    ActualisationNP2.s = IPS_ALERT;
559                    IDSetNumber(&ActualisationNP2, "Error ! Delay invalid");
560                }
561            }
562        }
563
564    } /* end EquatorialCoordsWNP */
565}
566
567/**************************************************************************************
568** L'utilisateur clique sur l'un des boutons de la boîte Indi
569***************************************************************************************/
570void BAO::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
571{
572    // ignore if not ours //
573    if (strcmp (mydev, dev))
574        return;
575
576    // ===================================
577    // Connect Switch
578    // ===================================
579    if (!strcmp (name, ConnectSP.name))
580    {
581        if (IUUpdateSwitch(&ConnectSP, states, names, n) < 0)
582            return;
583
584        connect_telescope();
585        return;
586    }
587
588    if (is_connected() == false)
589    {
590        IDMessage(mydev, "Error ! BAORadio is offline. Please connect before issuing any commands.");
591        reset_all_properties();
592        return;
593    }
594
595    // ===================================
596    // Coordinate Set
597    // ===================================
598    if (!strcmp(name, OnCoordSetSP.name))
599    {
600        if (IUUpdateSwitch(&OnCoordSetSP, states, names, n) < 0)
601            return;
602
603        currentSet = get_switch_index(&OnCoordSetSP);
604        OnCoordSetSP.s = IPS_OK;
605        IDSetSwitch(&OnCoordSetSP, NULL);
606    }
607
608    // ===================================
609    // Abort slew
610    // ===================================
611    if (!strcmp (name, AbortSlewSP.name))
612    {
613        Abort=true;
614
615        IUResetSwitch(&AbortSlewSP);
616
617        /*
618        if (EquatorialCoordsWNP.s == IPS_BUSY)
619        {
620
621        AbortSlewSP.s = IPS_OK;
622        EquatorialCoordsWNP.s       = IPS_IDLE;
623        EquatorialCoordsRNP.s       = IPS_IDLE;
624        HorizontalCoordsWNP.s       = IPS_IDLE;
625        IDSetSwitch(&AbortSlewSP, "Slew aborted.");
626        IDSetNumber(&EquatorialCoordsWNP, NULL);
627        IDSetNumber(&EquatorialCoordsRNP, NULL);
628        IDSetNumber(&HorizontalCoordsWNP, NULL);
629        }
630        */
631        return;
632    }
633
634
635    // ===================================
636    // Park
637    // ===================================
638    if (!strcmp (name, ParkSP.name))
639    {
640        Park=true;
641
642        IUResetSwitch(&ParkSP);
643
644        /*
645        if (EquatorialCoordsWNP.s == IPS_BUSY)
646        {
647
648        AbortSlewSP.s = IPS_OK;
649        EquatorialCoordsWNP.s       = IPS_IDLE;
650        EquatorialCoordsRNP.s       = IPS_IDLE;
651        HorizontalCoordsWNP.s       = IPS_IDLE;
652        IDSetSwitch(&AbortSlewSP, "Slew aborted.");
653        IDSetNumber(&EquatorialCoordsWNP, NULL);
654        IDSetNumber(&EquatorialCoordsRNP, NULL);
655        IDSetNumber(&HorizontalCoordsWNP, NULL);
656        }
657        */
658        return;
659    }
660}
661
662/**************************************************************************************
663** fct peut-être inutile
664***************************************************************************************/
665void BAO::handle_error(INumberVectorProperty *nvp, int err, const char *msg)
666{
667    nvp->s = IPS_ALERT;
668
669    /* If the error is a time out, then the device doesn't support this property */
670    if (err == -2)
671    {
672        nvp->s = IPS_ALERT;
673        IDSetNumber(nvp, "Device timed out. Current device may be busy or does not support %s. Will retry again.", msg);
674    }
675    else
676        /* Changing property failed, user should retry. */
677        IDSetNumber( nvp , "%s failed.", msg);
678
679    fault = true;
680}
681
682/**************************************************************************************
683** Initialisation des vecteurs INDI
684***************************************************************************************/
685void BAO::reset_all_properties()
686{
687    ConnectSP.s                 = IPS_IDLE;
688    OnCoordSetSP.s              = IPS_IDLE;
689    AbortSlewSP.s               = IPS_IDLE;
690    ParkSP.s                    = IPS_IDLE;
691    ObjectTP.s                  = IPS_IDLE;
692    EquatorialCoordsWNP.s       = IPS_IDLE;
693    //EquatorialCoordsRNP.s     = IPS_IDLE;
694    GeographicCoordsWNP.s       = IPS_IDLE;
695    //SlewAccuracyNP.s          = IPS_IDLE;
696    //TrackAccuracyNP.s         = IPS_IDLE;
697    ActualisationNP1.s          = IPS_IDLE;
698    ActualisationNP2.s          = IPS_IDLE;
699
700    IUResetSwitch(&OnCoordSetSP);
701    IUResetSwitch(&AbortSlewSP);
702    IUResetSwitch(&ParkSP);
703
704    OnCoordSetS[0].s = ISS_ON;
705    ConnectS[0].s = ISS_OFF;
706    ConnectS[1].s = ISS_ON;
707
708    IDSetSwitch(&ConnectSP, NULL);
709    IDSetSwitch(&OnCoordSetSP, NULL);
710    IDSetSwitch(&AbortSlewSP, NULL);
711    IDSetSwitch(&ParkSP, NULL);
712    IDSetText(&ObjectTP, NULL);
713    IDSetNumber(&EquatorialCoordsWNP, NULL);
714    //IDSetNumber(&EquatorialCoordsRNP, NULL);
715    IDSetNumber(&GeographicCoordsWNP, NULL);
716    //IDSetNumber(&SlewAccuracyNP, NULL);
717    //IDSetNumber(&TrackAccuracyNP, NULL);
718    IDSetNumber(&ActualisationNP1, NULL);
719    IDSetNumber(&ActualisationNP2, NULL);
720
721}
722
723/**************************************************************************************
724**
725***************************************************************************************/
726void BAO::correct_fault()
727{
728    fault = false;
729    IDMessage(mydev, "Telescope is online.");
730}
731
732/**************************************************************************************
733**
734***************************************************************************************/
735bool BAO::is_connected()
736{
737    if (simulation) return true;
738
739    // return (ConnectSP.sp[0].s == ISS_ON);
740    return (ConnectSP.s == IPS_OK);
741}
742
743/**************************************************************************************
744**
745***************************************************************************************/
746static void retry_connection(void * p)
747{
748
749}
750
751
752/**************************************************************************************
753** Extraction de la position de l'antenne
754** dans le retour de la commande POS
755** POS/Valeur az/Valeur alt
756***************************************************************************************/
757
758Position BAO::ExtractPosition(std::string str)
759{
760    Position result;
761
762    std::string str2;
763
764    result.x = -1;
765    result.y = -1;
766
767    int pos = str.find("/");
768
769    if (pos != string::npos)
770    {
771        str2 = str.substr(pos+1);
772
773        pos = str2.find("/");
774
775        if (pos != string::npos)
776        {
777            result.x = atoi(str2.substr(0, pos).c_str());
778
779            result.y = atoi(str2.substr(pos+1).c_str());
780        }
781    }
782
783    return result;
784}
785
786
787
788/************************************************************************************
789* cette procédure convertit les coordonnées equatoriales de l'objet visé
790* en unités de codeurs des paraboles (nb de tours des deux axes moteurs depuis la position PARK)
791************************************************************************************/
792void BAO::ADDEC2Motor(double newRA, double newDEC)
793{
794    double targetAz;
795    double targetAlt;
796    char AzStr[32];
797    char AltStr[32];
798
799    // Calcule la hauteur et l'azimut de la zone du ciel pointée (en fonction de la date et du lieu)
800
801    Azimut(tsl, Latitude, newRA * 15.0 * Pidiv180, newDEC * Pidiv180, &targetAz, &targetAlt);
802
803    // En degrés
804
805    targetAlt *= N180divPi;
806    targetAz *= N180divPi;
807
808    // Affichage dans les logs
809
810    fs_sexa(AzStr, targetAz, 2, 3600);
811    fs_sexa(AltStr, targetAlt, 2, 3600);
812
813    IDLog("Horizontal coords : az %s - Alt %s\n", AzStr, AltStr);
814
815    // Le calcul est ici trÚs sommaire et arbitraire :
816    // Je considÚre qu'il y a 100 positions possibles sur les deux axes
817    // De plus, je considÚre qu'il n'est pas possible de viser un objet à
818    // moins de 30° de hauteur au-dessus de l'horizon
819
820    TargetPosition.x=(int)(targetAz*100.0/360.0);
821
822    targetAlt=((90.0-targetAlt)/60.0);
823
824    if (targetAlt>=1.0)
825    {
826        targetAlt=1.0; //on ne peut pas viser un objet situé à moins de 30°
827        //au-dessus de l'horizon
828
829        IDSetSwitch(&OnCoordSetSP, "Erreur ! L objet suivi est situe a moins de 30° au-dessus de l horizon. Goto annule.");
830
831        Goto=false;
832
833        LecturePosition=false;
834
835        InitAntennes();
836    }
837
838    TargetPosition.y=(int)(100.0*targetAlt);
839}
840
841
842/************************************************************************************
843* Retourne simplement le nombre d'antennes connectées
844* et capables de communiquer
845************************************************************************************/
846
847int BAO::AntennesConnectees()
848{
849    int num=0;
850
851    for (int i=1; i<SocketsNumber; i++) if (Sockets[i].Connected) num++;
852
853    return num;
854}
855
856
857/************************************************************************************
858* Initialisation des paramÚtres des antennes
859*
860************************************************************************************/
861void BAO::InitAntennes()
862{
863    for (int i=0; i < MAXHOSTNAME ; i++)
864    {
865        Sockets[i].status=0;
866        Sockets[i].sendalertes=0;
867        Sockets[i].AttenteExecution=0;
868        Sockets[i].AnomaliesExecution=0;
869        Sockets[i].etape=0;
870
871        Sockets[i].ack_status=false;
872        Sockets[i].ack_pos=false;
873        Sockets[i].ack_park=false;
874        Sockets[i].ack_abort=false;
875        Sockets[i].ack_goto=false;
876
877        Sockets[i].PosValides=false;
878        Sockets[i].GotoOk=false;
879    }
880}
881
882
883/**************************************************************************************
884** Procédure principale
885** Elle est appelée toutes les POLLMS ms (ici 1 ms)
886***************************************************************************************/
887void BAO::ISPoll()
888{
889    static bool ISPOLLRunning=false;
890    static int memSocketsNumber=-1;
891    static unsigned int compt=100;
892
893    int pos;
894
895    struct tm date;
896    time_t t;
897    struct timeval tv;
898    struct timezone tz;
899
900    if (is_connected() == false) return;
901
902    if (ISPOLLRunning) return;
903
904    ISPOLLRunning=true;
905
906    compt++;
907
908
909    //toutes les 100 millisec
910
911    if ( compt%100 == 0)
912    {
913        //Récupération de la date et de l'heure
914
915        time(&t);
916        date=*gmtime(&t);
917        gettimeofday(&tv, &tz);
918
919        Annee=(double)(date.tm_year+1900);
920        Mois=(double)(date.tm_mon+1);
921        Jour=(double)date.tm_mday;
922        Heu=(double)date.tm_hour;
923        Min=(double)date.tm_min;
924        Sec=(double)date.tm_sec+tv.tv_usec/1.0E6;
925        UTCP=0.0;//(double)date.tm_isdst;
926
927
928        //Calcul du temps sidéral local
929
930        CalculTSL();
931
932
933        //Y a-t-il de nouvelles tentatives de connexion sur le serveur ?
934
935        InitThread();
936    }
937
938
939
940
941    if (InitThreadOK)  // Il faut qu'il y ait eu au moins une connexion détectée par le thread pour continuer
942    {
943
944        // Nouvelle connexion sur le socket !
945
946        if (SocketsNumber>memSocketsNumber)
947        {
948            memSocketsNumber=SocketsNumber;
949
950            IDSetSwitch(&ConnectSP, "Connexion de l antenne %s. (Antennes connectees : %i)",
951                        Sockets[SocketsNumber-1].IP.c_str(), AntennesConnectees());
952        }
953
954
955
956        // Début des échanges avec les microcontrÃŽleurs
957
958        // Analyse des réponses des microcontrÃŽleurs
959
960        for (int i=1; i<SocketsNumber; i++) /*if (Sockets[i].Connected)*/
961        {
962            try
963            {
964                std::string reponse, memreponse;
965                // on récupÚre la réponse du microcontrÃŽleur
966
967                Sockets[i].new_sock >> reponse;
968
969                //IDSetSwitch(&OnCoordSetSP, "Réponse ISPOLL : %s\n", reponse.c_str());        // pour vérif
970
971                //Dans le cas où plusieurs trames seraient arrivées entre deux appels de POLLMS
972                //les traiter successivement
973
974                pos=reponse.find("\n");   // d'où l'intérêt de mettre un '\n' à la fin des trames
975                //pour différencier une trame de la précédente
976
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("POSITION")!=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("POSITION")!=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 connectees !");
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 recu apres l ordre POSITION. \
1273                                Deconnexion de l antenne.", 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 retournee n est pas valide. \
1309                                Deconnexion de l antenne.", 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 recu apres l ordre GOTO. \
1346                                Deconnexion de l antenne.", 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 renvoye GOTO/OK. \
1383                                Deconnexion de l antenne.", 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, "Erreur sur l antenne %s : deconnexion de l antenne.", Sockets[i].IP.c_str());
1413
1414                        Sockets[i].Connected=false;
1415                    }
1416                }
1417            }
1418
1419
1420
1421        //On attend que toutes les antennes soient prêtes pour lancer l'ordre Goto -> meilleure synchronisation
1422
1423        int num=0;
1424
1425        for (int i=1; i<SocketsNumber; i++) if (Sockets[i].Connected)
1426            {
1427                if (Sockets[i].etape == 3) num++; //fin de la procédure LecturePosition. Les antennes sont prêtes
1428                //à recevoir l'ordre GOto
1429            }
1430
1431        if ((num == AntennesConnectees()) && (num>0))
1432        {
1433            for (int i=1; i<SocketsNumber; i++ ) if (Sockets[i].Connected)
1434                {
1435                    Sockets[i].ack_goto=false;
1436                    Sockets[i].AttenteExecution=0;
1437                    Sockets[i].AnomaliesExecution=0;
1438
1439                    if (!GOTO(i, Sockets[i].Pos.x - TargetPosition.x, Sockets[i].Pos.y - TargetPosition.y )) Sockets[i].sendalertes++;
1440
1441                    Sockets[i].etape++;
1442                }
1443        }
1444    }
1445
1446    ISPOLLRunning=false;
1447}
1448
1449
1450
1451/**************************************************************************************
1452**
1453***************************************************************************************/
1454bool BAO::process_coords()
1455{
1456    switch (currentSet)
1457    {
1458        // Transit
1459    case BAO_TRANSIT:
1460
1461        EquatorialCoordsWNP.s = IPS_BUSY;
1462
1463        IDSetNumber (&EquatorialCoordsWNP, NULL);
1464
1465        InitAntennes();
1466
1467        JJAnc=JJ;
1468
1469        TrackingMode = 1;
1470
1471        Goto=true;
1472
1473        LastGotoOK=false;
1474
1475        LecturePosition=true;
1476
1477        ADDEC2Motor(targetRA, targetDEC);
1478
1479        break;
1480
1481        // Tracking
1482    case BAO_TRACKING:
1483
1484        EquatorialCoordsWNP.s = IPS_BUSY;
1485
1486        IDSetNumber (&EquatorialCoordsWNP, NULL);
1487
1488        InitAntennes();
1489
1490        JJAnc=JJ;
1491
1492        TrackingMode = 2;
1493
1494        Goto=true;
1495
1496        LastGotoOK=false;
1497
1498        LecturePosition=true;
1499
1500        ADDEC2Motor(targetRA, targetDEC);
1501
1502        break;
1503    }
1504
1505    return true;
1506}
1507
1508/**************************************************************************************
1509**
1510***************************************************************************************/
1511int BAO::get_switch_index(ISwitchVectorProperty *sp)
1512{
1513    for (int i=0; i < sp->nsp ; i++)
1514        if (sp->sp[i].s == ISS_ON)
1515            return i;
1516
1517    return -1;
1518}
1519
1520/**************************************************************************************
1521** Activation de l'interface
1522***************************************************************************************/
1523void BAO::connect_telescope()
1524{
1525    switch (ConnectSP.sp[0].s)
1526    {
1527    case ISS_ON:
1528        ConnectS[0].s = ISS_ON;
1529        ConnectS[1].s = ISS_OFF;
1530        IDLog("\nHello BAORadio !\n");
1531
1532        ConnectSP.s = IPS_OK;
1533        IDSetSwitch (&ConnectSP, "BAORadio is online. Retrieving basic data...");
1534
1535
1536        break;
1537
1538    case ISS_OFF:
1539        ConnectS[0].s = ISS_OFF;
1540        ConnectS[1].s = ISS_ON;
1541        ConnectSP.s = IPS_IDLE;
1542
1543        SocketsNumber=1;
1544        InitThreadOK=false;
1545
1546        for (int i=0; i<MAXHOSTNAME; i++)
1547        {
1548            Sockets[i].Connected=false;
1549            Sockets[i].IP="";
1550            Sockets[i].new_sock.shutdown();
1551        }
1552
1553        InitAntennes();
1554
1555        IDSetSwitch (&ConnectSP, "BAORadio is offline.");
1556        IDLog("Telescope is offline.");
1557
1558        break;
1559    }
1560}
1561
1562/**************************************************************************************
1563**
1564***************************************************************************************/
1565void BAO::get_initial_data()
1566{
1567    //  IDSetNumber (&EquatorialCoordsRNP, NULL);
1568
1569
1570}
1571
1572/**************************************************************************************
1573**
1574***************************************************************************************/
1575void BAO::slew_error(int slewCode)
1576{
1577    OnCoordSetSP.s = IPS_IDLE;
1578
1579    if (slewCode == 1)
1580        IDSetSwitch (&OnCoordSetSP, "Object below horizon.");
1581    else if (slewCode == 2)
1582        IDSetSwitch (&OnCoordSetSP, "Object below the minimum elevation limit.");
1583    else
1584        IDSetSwitch (&OnCoordSetSP, "Slew failed.");
1585}
1586
1587/**************************************************************************************
1588**
1589***************************************************************************************/
1590void BAO::enable_simulation(bool enable)
1591{
1592    simulation = enable;
1593
1594    if (simulation)
1595        IDLog("Warning: Simulation is activated.\n");
1596    else
1597        IDLog("Simulation is disabled.\n");
1598}
1599
1600/**************************************************************************************
1601**
1602***************************************************************************************/
1603void BAO::connection_lost()
1604{
1605    ConnectSP.s = IPS_IDLE;
1606    IDSetSwitch(&ConnectSP, "The connection to the telescope is lost.");
1607    return;
1608}
1609
1610/**************************************************************************************
1611**
1612***************************************************************************************/
1613void BAO::connection_resumed()
1614{
1615    ConnectS[0].s = ISS_ON;
1616    ConnectS[1].s = ISS_OFF;
1617    ConnectSP.s = IPS_OK;
1618
1619    IDSetSwitch(&ConnectSP, "The connection to the telescope has been resumed.");
1620}
1621
1622
1623/**************************************************************************************
1624**  Envoi d'une commande sur le socket puis attente de l'acknowledge
1625***************************************************************************************/
1626
1627bool BAO::COMMANDE(int numsocket, char* Commande, char* Params)
1628{
1629    char chaine[MAXCARACTERES];
1630
1631    try
1632    {
1633        sprintf(chaine, "%s%s\n", Commande, Params);
1634
1635        Sockets[numsocket].new_sock << chaine;
1636    }
1637    catch (SocketException& e)
1638    {
1639        Sockets[numsocket].new_sock.shutdown();
1640        Sockets[numsocket].new_sock.create();
1641        Sockets[numsocket].Connected = Sockets[numsocket].new_sock.connect((std::string)Sockets[numsocket].IP);
1642
1643        if (Sockets[numsocket].Connected)
1644        {
1645            Sockets[numsocket].AttenteExecution=0;
1646            Sockets[numsocket].AnomaliesExecution=0;
1647        }
1648
1649        //  if (AntennesConnectees() == 0) { InitAntennes(); InitThreadOK=false;}
1650
1651        std::string oss;
1652        oss="COMMANDE exception : " + e.description() + "\n";
1653        size_t size = oss.size() + 1;
1654        char* buffer = new char[size];
1655        strncpy(buffer, oss.c_str(), size);
1656
1657        IDLog(buffer);
1658
1659        delete [] buffer;
1660
1661        return false;
1662    }
1663
1664    return true;
1665}
1666
1667
1668/**************************************************************************************
1669** Commande POSITION
1670***************************************************************************************/
1671
1672bool BAO::POSITION(int numsocket)
1673{
1674    return COMMANDE(numsocket, (char*)"P", (char*)"");
1675}
1676
1677/**************************************************************************************
1678** Commande PARK
1679***************************************************************************************/
1680
1681bool BAO::PARK(int numsocket)
1682{
1683    return COMMANDE(numsocket, (char*)"Z", (char*)"");
1684}
1685
1686/**************************************************************************************
1687** Commande ABORT
1688***************************************************************************************/
1689
1690bool BAO::ABORT(int numsocket)
1691{
1692    return COMMANDE(numsocket, (char*)"A", (char*)"");
1693}
1694
1695
1696/**************************************************************************************
1697** Commande GOTO
1698***************************************************************************************/
1699
1700bool BAO::GOTO(int numsocket, int deltaAz, int deltaAlt)
1701{
1702    char Params[MAXCARACTERES];
1703    char sensAz;
1704    char sensAlt;
1705
1706    sensAlt='b';
1707    sensAz='b';
1708
1709    if (deltaAz<0)
1710    {
1711        deltaAz=-deltaAz;
1712        sensAz='f';
1713    }
1714
1715    if (deltaAlt<0)
1716    {
1717        deltaAlt=-deltaAlt;
1718        sensAlt='f';
1719    }
1720
1721    sprintf(Params, "%c%04i%c%04i", sensAz, deltaAz, sensAlt, deltaAlt);
1722
1723    return COMMANDE(numsocket, (char*)"G", Params);
1724}
1725
1726
1727
Note: See TracBrowser for help on using the repository browser.