source: BAORadio/libindi/libindi/drivers/telescope/BAO.cpp @ 619

Last change on this file since 619 was 619, checked in by frichard, 13 years ago
File size: 59.0 KB
Line 
1/*
2#############################
3##
4## BAORadio Indi driver
5## Franck RICHARD
6## franckrichard033@gmail.com
7## Décembre 2011
8##
9#############################
10*/
11
12#include "BAO.h"
13
14
15auto_ptr<BAO> telescope(0);
16
17const int  POLLMS = 1;                                  // Period of update, 1 ms.
18
19const char *mydev = "BAO";                              // Name of our device.
20
21const char *BASIC_GROUP    = "Main Control";            // Main Group
22const char *OPTIONS_GROUP  = "Options";                 // Options Group
23
24/* Handy Macros */
25//#define currentRA     EquatorialCoordsRN[0].value
26//#define currentDEC    EquatorialCoordsRN[1].value
27#define targetRA        EquatorialCoordsWN[0].value
28#define targetDEC       EquatorialCoordsWN[1].value
29
30
31static void ISPoll(void *);
32
33void* LancementThread(BAO * appli);
34
35
36/**************************************************************************************
37** Initialisation de la classe BAO
38***************************************************************************************/
39
40BAO::BAO()
41{
42    init_properties();
43
44    // télescope en état IDLE
45    ConnectSP.s    = IPS_IDLE;
46
47    // derniÚre actualisation
48    lastRA         = 0.0;
49    lastDEC        = 0.0;
50    JJAnc          = 0.0;
51
52    currentSet     =  0;
53    lastSet        = -1;
54    SocketsNumber  =  1;
55    TrackingMode   =  1;
56
57    // délais en sec entre deux actualisations de la
58    // position dans les modes transit et tracking
59
60    ActualisationTM1 = 15.0 * 60.0;
61    ActualisationTM2 = 5.0;
62
63    UpdateGoto      = true;
64    InitThreadOK    = false;
65    ActualisationPosition = false;
66    Abort           = false;
67    Park            = false;
68    Suivi           = false;
69    Exit            = false;
70
71
72    // initialisation des sockets (Antennes)
73   
74    for (int i=0; i<MAXHOSTNAME; i++)
75    {
76        Sockets[i].Connected = false;
77        Sockets[i].IP = "";
78               
79        Sockets[i].Delta.x = 0.0;
80        Sockets[i].Delta.y = 0.0;
81    }
82
83    // initialisations supplémentaires
84   
85    InitAntennes();
86
87    // Numéro de version
88   
89    IDLog("Initilizing from BAO device...\n");
90    IDLog("Driver Version: 2011-12-02\n");
91
92    //connect_telescope();
93}
94
95
96/**************************************************************************************
97** Destructeur
98** Lorsque l'on lance indi_BAO depuis indiserver dans un terminal
99** Le destructeur ne semble jamais être atteint lorsque l'on sort... A vérifier
100***************************************************************************************/
101BAO::~BAO()
102{
103    Exit = true;
104    sleep(1);
105    pthread_join (th1, NULL);
106}
107
108
109/************************************************************************************
110* Initialisation des paramÚtres des antennes
111*
112************************************************************************************/
113void BAO::InitAntennes()
114{
115    for (int i=0; i<MAXHOSTNAME; i++)
116    {
117        Sockets[i].status             = 0;
118        Sockets[i].sendalertes        = 0;
119        Sockets[i].AttenteExecution   = 0;
120        Sockets[i].AnomaliesExecution = 0;
121        Sockets[i].etape              = 0;
122
123        Sockets[i].ack_status = false;
124        Sockets[i].ack_pos    = false;
125        Sockets[i].ack_park   = false;
126        Sockets[i].ack_abort  = false;
127        Sockets[i].ack_goto   = false;
128
129        Sockets[i].PosValides = false;
130        Sockets[i].GotoOk     = false;
131    }
132}
133
134
135/**************************************************************************************
136** Initialisation des boutons et des zones d'affichage dans la boîte de dialogue INDI
137***************************************************************************************/
138
139void BAO::init_properties()
140{
141    // Connection
142    IUFillSwitch(&ConnectS[0], "CONNECT", "Connect", ISS_OFF);
143    IUFillSwitch(&ConnectS[1], "DISCONNECT", "Disconnect", ISS_ON);
144    IUFillSwitchVector(&ConnectSP, ConnectS, NARRAY(ConnectS), mydev, "CONNECTION", "Connection", BASIC_GROUP, IP_RW, ISR_1OFMANY, 60, IPS_IDLE);
145
146    // Coord Set
147    IUFillSwitch(&OnCoordSetS[0], "TRANSIT", "Transit", ISS_ON);
148    IUFillSwitch(&OnCoordSetS[1], "TRACKING", "Tracking", ISS_OFF);
149    IUFillSwitchVector(&OnCoordSetSP, OnCoordSetS, NARRAY(OnCoordSetS), mydev, "ON_COORD_SET", "On Set", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
150
151    // Abort
152    IUFillSwitch(&AbortSlewS[0], "ABORT", "Abort", ISS_OFF);
153    IUFillSwitchVector(&AbortSlewSP, AbortSlewS, NARRAY(AbortSlewS), mydev, "ABORT_MOTION", "Abort", BASIC_GROUP, IP_RW, ISR_ATMOST1, 0, IPS_IDLE);
154
155    // Park
156    IUFillSwitch(&ParkS[0], "PARK", "Park", ISS_OFF);
157    IUFillSwitchVector(&ParkSP, ParkS, NARRAY(ParkS), mydev, "", "Park", BASIC_GROUP, IP_RW, ISR_ATMOST1, 0, IPS_IDLE);
158
159    // Object Name
160    IUFillText(&ObjectT[0], "OBJECT_NAME", "Name", "--");
161    IUFillTextVector(&ObjectTP, ObjectT, NARRAY(ObjectT), mydev, "OBJECT_INFO", "Object", BASIC_GROUP, IP_RW, 0, IPS_IDLE);
162
163    // Equatorial Coords - SET
164    IUFillNumber(&EquatorialCoordsWN[0], "RA", "RA  H:M:S", "%10.6m",  0., 24., 0., 0.);
165    IUFillNumber(&EquatorialCoordsWN[1], "DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0.);
166    IUFillNumberVector(&EquatorialCoordsWNP, EquatorialCoordsWN, NARRAY(EquatorialCoordsWN), mydev, "EQUATORIAL_EOD_COORD_REQUEST" , "Equatorial JNow", BASIC_GROUP, IP_WO, 0, IPS_IDLE);
167
168    // Geographic coord - SET
169    IUFillNumber(&GeographicCoordsWN[0], "LAT", "Lat  D", "%10.6m",  -90., 90., 0., 0.);
170    IUFillNumber(&GeographicCoordsWN[1], "LONG", "Long D", "%10.6m", 0., 360., 0., 0.);
171    IUFillNumberVector(&GeographicCoordsWNP, GeographicCoordsWN, NARRAY(GeographicCoordsWN), mydev, "GEOGRAPHIC_COORD" , "Geographic coords", OPTIONS_GROUP, IP_WO, 0, IPS_IDLE);
172
173    // Actualisation - SET
174    IUFillNumber(&ActualisationN1[0], "DELAY", "Transit mode delay (Sec)", "%10.6m",  0., 3600., 0., 0.);
175    IUFillNumberVector(&ActualisationNP1, ActualisationN1, NARRAY(ActualisationN1), mydev, "DELAY1" , "", OPTIONS_GROUP, IP_WO, 0, IPS_IDLE);
176
177    IUFillNumber(&ActualisationN2[0], "DELAY", "Tracking mode delay (Sec)", "%10.6m",  0., 3600., 0., 0.);
178    IUFillNumberVector(&ActualisationNP2, ActualisationN2, NARRAY(ActualisationN2), mydev, "DELAY2" , "", OPTIONS_GROUP, IP_WO, 0, IPS_IDLE);
179}
180
181
182/**************************************************************************************
183** Initialisation de la boîte de dialogue INDI (suite)
184***************************************************************************************/
185
186void BAO::ISGetProperties(const char *dev)
187{
188
189    if (dev && strcmp (mydev, dev))
190        return;
191
192    // Main Control
193    IDDefSwitch(&ConnectSP, NULL);
194    IDDefText(&ObjectTP, NULL);
195    IDDefNumber(&EquatorialCoordsWNP, NULL);
196    IDDefNumber(&GeographicCoordsWNP, NULL);
197    IDDefSwitch(&OnCoordSetSP, NULL);
198    IDDefSwitch(&AbortSlewSP, NULL);
199    IDDefSwitch(&ParkSP, NULL);
200
201    // Options
202    IDDefNumber(&ActualisationNP1, NULL);
203    IDDefNumber(&ActualisationNP2, NULL);
204}
205
206
207/**************************************************************************************
208** Initialisation des vecteurs INDI
209***************************************************************************************/
210
211void BAO::reset_all_properties()
212{
213    ConnectSP.s                 = IPS_IDLE;
214    OnCoordSetSP.s              = IPS_IDLE;
215    AbortSlewSP.s               = IPS_IDLE;
216    ParkSP.s                    = IPS_IDLE;
217    ObjectTP.s                  = IPS_IDLE;
218    EquatorialCoordsWNP.s       = IPS_IDLE;
219    GeographicCoordsWNP.s       = IPS_IDLE;
220    ActualisationNP1.s          = IPS_IDLE;
221    ActualisationNP2.s          = IPS_IDLE;
222
223    IUResetSwitch(&OnCoordSetSP);
224    IUResetSwitch(&AbortSlewSP);
225    IUResetSwitch(&ParkSP);
226
227    OnCoordSetS[0].s = ISS_ON;
228    ConnectS[0].s = ISS_OFF;
229    ConnectS[1].s = ISS_ON;
230
231    IDSetSwitch(&ConnectSP, NULL);
232    IDSetSwitch(&OnCoordSetSP, NULL);
233    IDSetSwitch(&AbortSlewSP, NULL);
234    IDSetSwitch(&ParkSP, NULL);
235    IDSetText(&ObjectTP, NULL);
236    IDSetNumber(&EquatorialCoordsWNP, NULL);
237    IDSetNumber(&GeographicCoordsWNP, NULL);
238    IDSetNumber(&ActualisationNP1, NULL);
239    IDSetNumber(&ActualisationNP2, NULL);
240}
241
242
243/**************************************************************************************
244** En cas de changement de texte dans la boîte de dialogue (par exemple : changement du
245** nom de l'objet) alors suivre l'objet...
246** Cette fonction n'est pas encore utilisée
247***************************************************************************************/
248
249void BAO::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
250{
251    // Ignore if not ours
252    if (strcmp (dev, mydev))
253        return;
254
255    if (is_connected() == false)
256    {
257        IDMessage(mydev, "Error ! Please connect before issuing any commands.");
258        reset_all_properties();
259        return;
260    }
261
262    // ===================================
263    // Object Name
264    // ===================================
265    if (!strcmp (name, ObjectTP.name))
266    {
267        if (IUUpdateText(&ObjectTP, texts, names, n) < 0)
268            return;
269
270        ObjectTP.s = IPS_OK;
271        IDSetText(&ObjectTP, NULL);
272        return;
273    }
274}
275
276
277/**************************************************************************************
278** En cas de changement d'une valeur numérique dans la boîte de dialogue Indi
279** Exemple : longitude, latitude, ar, dec etc...) -> prendre en compte les modifications
280**
281***************************************************************************************/
282
283void BAO::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
284{
285
286    // Ignore if not ours
287    if (strcmp (dev, mydev))
288        return;
289
290    if (is_connected() == false)
291    {
292        IDMessage(mydev, "Error ! BAO is offline. Please connect before issuing any commands.");
293        reset_all_properties();
294        return;
295    }
296
297
298    // ===================================
299    // Geographic  Coords
300    // ===================================
301    if (!strcmp (name, GeographicCoordsWNP.name))
302    {
303        int i=0, nset=0, error_code=0;
304
305        Latitude=0.0;
306        Longitude=0.0;
307
308        for (nset = i = 0; i < n; i++)
309        {
310            INumber *eqp = IUFindNumber (&GeographicCoordsWNP, names[i]);
311            if (eqp == &GeographicCoordsWN[0])
312            {
313                Latitude = values[i];
314                nset += Latitude >= -90.0 && Latitude <= 90.0;
315
316                Latitude *= Pidiv180;
317            }
318            else if (eqp == &GeographicCoordsWN[1])
319            {
320                Longitude = values[i];
321                nset += Longitude >= 0.0 && Longitude <= 360.0;
322
323                Longitude *= -Pidiv180;
324            }
325        }
326
327        // Si la longitude et la latitude sont correctes
328        // on envoie les coordonnées à la classe Astro
329        if (nset == 2)
330        {
331            //Vérification
332            //IDLog("Geographic : RA %5.2f - DEC %5.2f\n", Latitude, Longitude);
333
334            GeographicCoordsWNP.s = IPS_OK;
335            IDSetNumber(&GeographicCoordsWNP, NULL);
336        }
337        else
338        {
339            GeographicCoordsWNP.s = IPS_ALERT;
340            IDSetNumber(&GeographicCoordsWNP, "Latitude or Longitude missing or invalid");
341
342            Latitude=0.0;
343            Longitude=0.0;
344        }
345
346        DefinirLongitudeLatitude(Longitude, Latitude);
347
348        return;
349    }
350
351
352    // ===================================
353    // Equatorial Coords
354    // ===================================
355    if (!strcmp (name, EquatorialCoordsWNP.name))
356    {
357        int i=0, nset=0, error_code=0;
358        double newRA =0, newDEC =0;
359
360        for (nset = i = 0; i < n; i++)
361        {
362            INumber *eqp = IUFindNumber (&EquatorialCoordsWNP, names[i]);
363            if (eqp == &EquatorialCoordsWN[0])
364            {
365                newRA = values[i];
366                nset += newRA >= 0 && newRA <= 24.0;
367            }
368            else if (eqp == &EquatorialCoordsWN[1])
369            {
370                newDEC = values[i];
371                nset += newDEC >= -90.0 && newDEC <= 90.0;
372            }
373        }
374
375
376        // si les coordonnées de l'objet sont correctes
377        if (nset == 2)
378        {
379            char RAStr[32], DecStr[32];
380            double targetAZ, targetAlt;
381
382            targetRA  = newRA;
383            targetDEC = newDEC;
384
385            fs_sexa(RAStr, newRA, 2, 3600);
386            fs_sexa(DecStr, newDEC, 2, 3600);
387
388            IDLog("We received JNow RA %s - DEC %s\n", RAStr, DecStr);
389
390            // on convertit les coordonnées équatoriales de la zone du ciel observée
391            // en unités de codeurs des moteurs
392
393            ADDEC2Motor(newRA, newDEC);
394
395            if (process_coords() == false)
396            {
397                EquatorialCoordsWNP.s = IPS_ALERT;
398                IDSetNumber(&EquatorialCoordsWNP, NULL);
399            }
400        }
401        else
402        {
403            EquatorialCoordsWNP.s = IPS_ALERT;
404            IDSetNumber(&EquatorialCoordsWNP, "Error ! RA or Dec missing or invalid");
405        }
406
407        return;
408    }
409
410    // ===================================
411    // Actualisation
412    // ===================================
413    if (!strcmp (name, ActualisationNP1.name))
414    {
415        int i=0, nset=0, error_code=0;
416        double newAct1 =0;
417
418        for (nset = i = 0; i < n; i++)
419        {
420            INumber *eqp = IUFindNumber (&ActualisationNP1, names[i]);
421            if (eqp == &ActualisationN1[0])
422            {
423                newAct1 = values[i];
424
425                if (newAct1 >= 0.0 && newAct1 <= 3600.0)
426                {
427                    ActualisationTM1 = newAct1;
428
429                    ActualisationNP1.s = IPS_OK;
430                    IDSetNumber(&ActualisationNP1, NULL);
431                }
432                else
433                {
434                    ActualisationNP1.s = IPS_ALERT;
435                    IDSetNumber(&ActualisationNP1, "Error ! Delay invalid");
436                }
437            }
438        }
439    }
440
441    if (!strcmp (name, ActualisationNP2.name))
442    {
443        int i=0, nset=0, error_code=0;
444        double newAct2 =0;
445
446        for (nset = i = 0; i < n; i++)
447        {
448            INumber *eqp = IUFindNumber (&ActualisationNP2, names[i]);
449            if (eqp == &ActualisationN2[0])
450            {
451                newAct2 = values[i];
452
453                if (newAct2 >= 0.0 && newAct2 <= 3600.0)
454                {
455                    ActualisationTM2 = newAct2;
456
457                    ActualisationNP2.s = IPS_OK;
458                    IDSetNumber(&ActualisationNP2, NULL);
459                }
460                else
461                {
462                    ActualisationNP2.s = IPS_ALERT;
463                    IDSetNumber(&ActualisationNP2, "Error ! Delay invalid");
464                }
465            }
466        }
467    }
468}
469
470
471/**************************************************************************************
472** L'utilisateur clique sur l'un des boutons de la boîte Indi
473***************************************************************************************/
474
475void BAO::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
476{
477    // ignore if not ours //
478    if (strcmp (mydev, dev))
479        return;
480
481    // ===================================
482    // Connect Switch
483    // ===================================
484    if (!strcmp (name, ConnectSP.name))
485    {
486        if (IUUpdateSwitch(&ConnectSP, states, names, n) < 0)
487            return;
488
489        connect_telescope();
490
491        return;
492    }
493
494    if (is_connected() == false)
495    {
496        IDMessage(mydev, "Error ! BAORadio is offline. Please connect before issuing any commands.");
497        reset_all_properties();
498        return;
499    }
500
501    // ===================================
502    // Coordinate Set
503    // ===================================
504    if (!strcmp(name, OnCoordSetSP.name))
505    {
506        if (IUUpdateSwitch(&OnCoordSetSP, states, names, n) < 0)
507            return;
508
509        currentSet = get_switch_index(&OnCoordSetSP);
510        OnCoordSetSP.s = IPS_OK;
511        IDSetSwitch(&OnCoordSetSP, NULL);
512    }
513
514    // ===================================
515    // Abort slew
516    // ===================================
517    if (!strcmp (name, AbortSlewSP.name))
518    {
519        Abort=true;
520
521        IUResetSwitch(&AbortSlewSP);
522
523        if (EquatorialCoordsWNP.s == IPS_OK)
524        {
525            AbortSlewSP.s = IPS_OK;
526            EquatorialCoordsWNP.s = IPS_IDLE;
527            ObjectTP.s = IPS_IDLE;
528
529            IDSetSwitch(&ConnectSP, "Envoi de la commande Abort\n");
530            IDSetNumber(&EquatorialCoordsWNP, NULL);
531            IDSetText(&ObjectTP, NULL);
532        }
533
534        return;
535    }
536
537
538    // ===================================
539    // Park
540    // ===================================
541    if (!strcmp (name, ParkSP.name))
542    {
543        Park=true;
544
545        IUResetSwitch(&ParkSP);
546
547        if (EquatorialCoordsWNP.s == IPS_OK)
548        {
549            AbortSlewSP.s = IPS_OK;
550            EquatorialCoordsWNP.s = IPS_IDLE;
551            ObjectTP.s = IPS_IDLE;
552
553            IDSetSwitch(&ConnectSP, "Envoi de la commande Park\n");
554            IDSetNumber(&EquatorialCoordsWNP, NULL);
555            IDSetText(&ObjectTP, NULL);
556        }
557
558        return;
559    }
560}
561
562
563
564/**************************************************************************************
565** Gestion du thread
566** permet de suivre la connexion/déconnexion des antennes toutes les secondes
567**
568** l'utilisation d'un thread permet de contourner le problÚme de la fonction accept
569** qui est bloquante.
570***************************************************************************************/
571
572void *BAO::pThreadSocket ()
573{
574    do
575    {
576        try
577        {
578            server.accept( Sockets[SocketsNumber].new_sock );
579
580            Sockets[SocketsNumber].IP = server.recupip(Sockets[SocketsNumber].new_sock);
581
582            Sockets[SocketsNumber++].Connected = true;
583
584            InitThreadOK = true;
585        }
586        catch ( SocketException& e )
587        {
588            /*IDLog("Indi_BAO, pThreadSocket exception : ");
589            IDLog(e.description().c_str());
590            IDLog("\n");*/
591        }
592       
593        sleep(1); // faire une pause pour éviter de consommer trop de temps CPU -> à vérifier
594    }
595    while (!Exit);
596
597    pthread_exit (0);
598}
599
600
601
602/**************************************************************************************
603** Astuce pour lancer le thread depuis la classe BAO
604**
605***************************************************************************************/
606
607void* LancementThread(BAO * appli)
608{
609    appli->pThreadSocket();
610
611    return 0;
612}
613
614
615/**************************************************************************************
616** Extraction de la position de l'antenne aprÚs l'envoi de la commande P
617** Le retour de la commande P est POSITION/valeur_az/valeur_alt/
618** ExtractPosition retourne donc Valeur_az et Valeur_alt
619***************************************************************************************/
620
621bool BAO::ExtractPosition(string str, Position *result)
622{
623    string str2;
624
625    int pos = str.find("/");
626
627    if (pos != string::npos)
628    {
629        str2 = str.substr(pos + 1);
630
631        pos = str2.find("/");
632
633        if (pos != string::npos)
634        {
635            result->x = atol(str2.substr(0, pos).c_str());
636
637            result->y = atol(str2.substr(pos + 1).c_str());
638           
639            return true;
640        }       
641    } 
642
643    IDLog((str +" failed !\n").c_str());
644
645    return false;
646}
647
648
649
650/************************************************************************************
651* cette procédure convertit les coordonnées équatoriales de l'objet visé
652* en unités de codeurs des paraboles (nb de tours des deux axes moteurs depuis la position PARK)
653************************************************************************************/
654
655void BAO::ADDEC2Motor(double newRA, double newDEC)
656{
657    double targetAz;
658    double targetAlt;
659    char AzStr[32];
660    char AltStr[32];
661
662
663    // Calcule la hauteur et l'azimut de la zone du ciel pointée (en fonction de la date et du lieu d'observation)
664
665    Azimut( newRA * 15.0 * Pidiv180, newDEC * Pidiv180, &targetAz, &targetAlt);
666   
667    // Correction de la réfraction atmosphérique
668   
669    targetAlt = RefractionAtmospherique(targetAlt);
670
671    // Petit calcul pour faire en sorte que le sud soit à 0° d'azimut
672
673    targetAz = VerifAngle( targetAz + Pi );
674
675    // On convertit les angles précédents en degrés
676
677    targetAlt *= N180divPi;
678    targetAz  *= N180divPi;
679
680    // Affichage dans les logs
681
682    fs_sexa(AzStr, targetAz, 2, 3600);
683    fs_sexa(AltStr, targetAlt, 2, 3600);
684
685    IDLog("Horizontal coords : Az = %s     Alt = %s\n", AzStr, AltStr);
686
687
688    //Conversion des deux angles en pas codeurs
689
690    if ( targetAlt < 30.0 )
691    {
692        // L'objet est trop bas (<30°). On annule le suivi...
693
694        IDSetSwitch(&OnCoordSetSP, "Erreur ! L objet suivi est situe a moins de 30° au-dessus de l horizon. Goto annule.");
695
696        Suivi = false;
697
698        ActualisationPosition = false;
699
700        InitAntennes();
701    }
702    else
703    {
704        // Si la hauteur est supérieure à 90°, on doit ajouter 180° à l'azimut et corriger
705        // la hauteur en appliquant hauteur=180°-hauteur
706
707        if (targetAlt > 90.0)
708        {
709            targetAlt = 180.0 - targetAlt;
710            targetAz += 180.0;
711        }
712
713        // On applique la formule de Marc pour convertir la hauteur en nombre de pas codeur alt
714
715        double I0 = 81.0;
716        double I2 = 128279.4 - 129723.4 * sin( (targetAlt - 20.2345) * Pidiv180 );
717
718        double Codalt = (sqrt(I2) - I0) / 0.078947;
719
720
721        TargetPosition.y = (int) Arrondi(Codalt);
722
723        //4000 pas pour 360° sur l'axe az
724
725        TargetPosition.x = (int) Arrondi( targetAz * 4000.0 / 360.0);
726
727        IDLog("Nbre de pas codeurs Az = %i        Alt = %i\n", TargetPosition.x, TargetPosition.y);
728    }
729}
730
731
732/**************************************************************************************
733** Le fichier file existe-t-il et n'est-il pas vide ?
734**************************************************************************************/
735
736bool BAO::is_readable( const std::string & file ) 
737{ 
738    std::ifstream fichier( file.c_str() ); 
739    if (fichier.fail()) return false;
740   
741    // sauvegarder la position courante
742    long pos = fichier.tellg();
743    // se placer en fin de fichier
744    fichier.seekg( 0 , std::ios_base::end );
745    // récupérer la nouvelle position = la taille du fichier
746    long size = fichier.tellg() ;
747    // restaurer la position initiale du fichier
748    fichier.seekg( pos,  std::ios_base::beg ) ;
749    return size ;
750}
751
752
753/**************************************************************************************
754** Chargement des paramÚtres d'alignement des antennes
755**************************************************************************************/
756
757bool BAO::ChargementParametresAlignement(string fileName)
758{
759    string value;
760   
761    stringstream os;
762   
763    char *delta_az = NULL;
764   
765    char *delta_ha = NULL;
766       
767    if (!is_readable(fileName)) return false;
768     
769    //IDLog("Chargement du fichier d alignement des antennes %s\n", fileName.c_str());
770     
771    //Chargement des corrections des antennes
772   
773    for (int i=0; i<SocketsNumber; i++)
774    {
775        if (Sockets[i].Connected)
776        {
777            os << "Alignement antenne ip x.x.x." << Sockets[i].IP.substr(Sockets[i].IP.rfind(".")+1);
778
779            value="delta_az";
780
781            if (readINI((char*)os.str().c_str(), (char*)value.c_str(), &delta_az,  (char*)fileName.c_str()))
782
783            value="delta_ha";
784
785            if (readINI((char*)os.str().c_str(), (char*)value.c_str(), &delta_ha,  (char*)fileName.c_str()))
786
787            if (delta_az && delta_ha)
788            {
789               // Si les corrections de l'antenne i ont été modifiées depuis le démarrage du programme
790               // -> on les applique...
791               if (Sockets[i].Delta.x != atol(delta_az) || Sockets[i].Delta.y != atol(delta_ha))
792               {
793                  Sockets[i].Delta.x = atol(delta_az);
794
795                  Sockets[i].Delta.y = atol(delta_ha);
796
797                  IDLog("Correction antenne ip %s  deltaAz=%i   deltaHa=%i\n", Sockets[i].IP.c_str(), Sockets[i].Delta.x, Sockets[i].Delta.y);
798               }
799            }
800
801            if (delta_az) {
802                delete [] delta_az;
803                delta_az=NULL;
804            }
805
806            if (delta_ha) {
807                delete [] delta_ha;
808                delta_ha=NULL;
809            }
810
811            os.str("");
812        }
813    }
814   
815    return true;
816}
817
818
819/************************************************************************************
820* Retourne le nombre d'antennes connectées
821*
822************************************************************************************/
823
824int BAO::AntennesConnectees()
825{
826    int num = 0;
827
828    for (int i=1; i<SocketsNumber; i++) if (Sockets[i].Connected) num++;
829
830    return num;
831}
832
833
834/**************************************************************************************
835** En cas de problÚme
836** Déconnecter l'antenne utilisant le socket num
837***************************************************************************************/
838
839void BAO::DeconnecterSocket(int num)
840{
841    IDLog("Deconnexion de l antenne : %s\n", Sockets[num].IP.c_str());
842    Sockets[num].new_sock.shutdown();
843    Sockets[num].Connected = false;
844    Sockets[num].IP = "";
845}
846
847
848/**************************************************************************************
849** Procédure principale
850** Elle est appelée toutes les ms
851***************************************************************************************/
852
853void BAO::ISPoll()
854{
855    static int memSocketsNumber = -1;      // Combien y avait-il d'antennes connectées lors de l'appel précédent d'ISPoll ?
856    static unsigned int compt   =  0;      // Compteur de la fonction ISPoll
857
858    struct tm date;
859    time_t t;
860    struct timeval tv;
861    struct timezone tz;
862
863    //si pas de connexion avec le seveur d'indi -> on sort
864
865    if (!is_connected()) return;
866
867
868    // toutes les 100 millisec, on actualise le jour julien
869    // le temps sidéral local etc...
870
871    if ( compt%100 == 0 )
872    {
873        //Récupération de la date et de l'heure
874
875        time(&t);
876        date=*gmtime(&t);
877        gettimeofday(&tv, &tz);
878
879        double Annee=(double)(date.tm_year+1900);
880        double Mois=(double)(date.tm_mon+1);
881        double Jour=(double)date.tm_mday;
882        double Heu=(double)date.tm_hour;
883        double Min=(double)date.tm_min;
884        double Sec=(double)date.tm_sec+tv.tv_usec/1.0E6;
885        double UTCP=0.0;//(double)date.tm_isdst;
886
887        // On transmet la date et l'heure à la classe Astro
888
889        DefinirDateHeure(Annee, Mois, Jour, Heu, Min, Sec);
890
891        //Puis on calule le temps sidéral local, le JJ etc.
892
893        CalculTSL();
894    }
895   
896    // On chargement les paramÚtres de corrections des antennes toutes les secondes
897   
898    if ( compt%1000 == 0 ) ChargementParametresAlignement("/home/" + (string)getenv("USER") + "/AlignementAntennes.cfg");
899
900
901    // Il faut que le thread soit actif
902
903    if (InitThreadOK)
904    {
905
906        // Nouvelle connexion sur le socket ?
907
908        if (SocketsNumber > memSocketsNumber)
909        {
910            memSocketsNumber = SocketsNumber;
911
912            IDSetSwitch(&ConnectSP, "Connexion de l antenne %s. (Antennes connectees : %i)",
913                        Sockets[SocketsNumber-1].IP.c_str(), AntennesConnectees());
914        }
915
916
917        /////////////////////////////////////////////////
918        // Début des échanges avec les microcontrÃŽleurs
919
920        // Analyse des réponses des microcontrÃŽleurs
921
922        for (int i=1; i<SocketsNumber; i++)
923        {
924            if (Sockets[i].Connected)
925            {
926                try
927                {
928                    string reponse, buffereponse;
929
930                    // on récupÚre la réponse du microcontrÃŽleur
931
932                    Sockets[i].new_sock >> reponse;
933
934                    // Dans le cas où plusieurs trames seraient arrivées entre deux appels de POLLMS
935                    // les traiter successivement
936
937                    // d'où l'intérêt de mettre un '\n' à la fin des trames
938                    // pour différencier une trame de la précédente
939
940                    int pos = reponse.find("\n");
941
942                    // S'il y a une réponse
943
944                    while ((pos != string::npos) && (reponse.length() > 1))
945                    {
946                        // on garde en stock la deuxiÚme partie de la trame
947                        // pour un traitement ultérieur
948                        buffereponse = reponse.substr(pos + 1);
949
950                        // Partie traitée
951                        reponse = reponse.substr(0, pos);
952                       
953                        IDLog("Reponse recue de %s : %s\n", Sockets[i].IP.c_str(), reponse.c_str());
954
955                        // On vérifie ici les acknowledges
956                        if ((reponse.find("ACK") != string::npos) && (reponse.find("NACK") == string::npos))
957                        {
958                            if (reponse.find("POSITION")  != string::npos)
959                            {
960                                Sockets[i].ack_pos=true;
961                            }
962                            else if (reponse.find("GOTO") != string::npos)
963                            {
964                                Sockets[i].ack_goto=true;
965                            }
966                            else if (reponse.find("PARK") != string::npos)
967                            {
968                                Sockets[i].ack_park=true;
969                            }
970                            else if (reponse.find("ABORT")!= string::npos)
971                            {
972                                Sockets[i].ack_abort=true;
973                            }
974                        }
975                        else
976                        {
977                            //réponse à la requête POSITION
978
979                            if (reponse.find("POSITION") != string::npos)
980                            {
981                                if (reponse.find("NACK") != string::npos)
982                                {
983                                    //problÚme concernant la commande P
984                                    OnCoordSetSP.s = IPS_ALERT;
985                                    IDSetSwitch(&OnCoordSetSP, "ALERTE antenne %s : position de l antenne inconnue !\n",
986                                                Sockets[i].IP.c_str());
987                                    Sockets[i].PosValides = false;
988                                    // Si la position de l'antenne est inconnue, on déconnecte l'antenne
989                                    Sockets[i].Connected  = false;
990                                }
991                                else if (Sockets[i].ack_pos)
992                                {                             
993                                    if ( Sockets[i].PosValides = (ExtractPosition(reponse, &Sockets[i].Pos) == true) )
994                                    {
995                                      OnCoordSetSP.s = IPS_OK;
996                                      IDSetSwitch(&OnCoordSetSP, "Antenne %s : POSITION OK  (x=%i, y=%i)\n",
997                                                Sockets[i].IP.c_str(), Sockets[i].Pos.x, Sockets[i].Pos.y);
998                                    }
999                                    else
1000                                    {
1001                                      OnCoordSetSP.s = IPS_ALERT;
1002                                      IDSetSwitch(&OnCoordSetSP, "Antenne %s : La position n est pas valide !\n",
1003                                                Sockets[i].IP.c_str());
1004                                    }
1005                                     
1006                                }
1007                            }
1008
1009                            //réponse à la requête PARK
1010
1011                            if (reponse.find("PARK") != string::npos)
1012                            {
1013                                if (reponse.find("NACK") != string::npos)
1014                                {
1015                                    ParkSP.s = IPS_ALERT;
1016                                    IDSetSwitch(&ParkSP, "ALERTE antenne %s : erreur PARK !\n", Sockets[i].IP.c_str());
1017                                }
1018                                else if (Sockets[i].ack_park && reponse.find("OK")!=string::npos)
1019                                {
1020                                    ParkSP.s = IPS_OK;
1021                                    IDSetSwitch(&ParkSP, "Antenne %s : PARK OK\n",  Sockets[i].IP.c_str());
1022                                }
1023                            }
1024
1025                            //réponse à la requête ABORT
1026
1027                            if (reponse.find("ABORT") != string::npos)
1028                            {
1029                                if (reponse.find("NACK") != string::npos)
1030                                {
1031                                    AbortSlewSP.s = IPS_ALERT;
1032                                    IDSetSwitch(&AbortSlewSP, "ALERTE antenne %s : erreur ABORT !\n",  Sockets[i].IP.c_str());
1033                                }
1034                                else if (Sockets[i].ack_abort && reponse.find("OK")!=string::npos)
1035                                {
1036                                    AbortSlewSP.s = IPS_OK;
1037                                    IDSetSwitch(&AbortSlewSP, "Antenne %s : ABORT OK\n",  Sockets[i].IP.c_str());
1038                                }
1039
1040                            }
1041
1042                            //réponse à la requête GOTO
1043
1044                            if (reponse.find("GOTO") != string::npos)
1045                            {
1046                                if (reponse.find("NACK") != string::npos)
1047                                {
1048                                    OnCoordSetSP.s = IPS_ALERT;
1049                                    IDSetSwitch(&OnCoordSetSP, "ALERTE antenne %s : Erreur GOTO !\n",  Sockets[i].IP.c_str());
1050                                    DeconnecterSocket(i);
1051                                }
1052                                else if (Sockets[i].ack_goto)
1053                                {
1054                                    if (reponse.find("OK") != string::npos)
1055                                    {
1056                                        // On a ici la confirmation que l'antenne 'i' a bien réalisé
1057                                        // le goto
1058
1059                                        // On prend note
1060
1061                                        Sockets[i].GotoOk = true;
1062
1063                                        // Message pour l'utilisateur
1064                                       
1065                                        OnCoordSetSP.s = IPS_OK;
1066                                        IDSetSwitch(&OnCoordSetSP, "Antenne %s : GOTO OK.\n",  Sockets[i].IP.c_str());
1067
1068                                        // Fin du Goto pour toutes les antennes ?
1069
1070                                        int num=0;
1071
1072                                        for (int j=1; j<SocketsNumber; j++)
1073                                        {
1074                                          if (Sockets[j].Connected)
1075                                            {
1076                                                if (Sockets[j].GotoOk) num++;
1077                                            }
1078                                        }
1079
1080                                        if ((num == AntennesConnectees()) && (num>0))
1081                                        {
1082                                            // C'est bon ! Tout marche bien...
1083                                            // On actualise l'AR et la dec dans la boîte de dialogue
1084
1085                                            lastRA  = targetRA;
1086                                            lastDEC = targetDEC;
1087
1088                                            // On a fini le mouvement. On attend le prochain goto...
1089
1090                                            ActualisationPosition=false;
1091
1092                                            // Réinitialisation des paramÚtres des antennes en vue d'un prochain goto
1093
1094                                            InitAntennes();
1095
1096                                            // On dessine les voyants de la boîte de dialogue en vert
1097                                            OnCoordSetSP.s = IPS_OK;
1098                                            EquatorialCoordsWNP.s = IPS_OK;
1099                                            IDSetNumber (&EquatorialCoordsWNP, NULL);
1100
1101                                            // Confirmation dans la boîte de dialogue que toutes
1102                                            // les antennes sont OK         
1103                                            OnCoordSetSP.s = IPS_OK;
1104                                            IDSetSwitch(&OnCoordSetSP, "GOTO OK !");
1105                                           
1106                                            UpdateGoto=true;
1107                                        }                                       
1108                                    }
1109                                }
1110                            }
1111                        }
1112
1113                        // On passe à la trame suivante si memreponse n'est pas vide
1114
1115                        reponse=buffereponse;
1116                        pos=reponse.find("\n");
1117                    }
1118                }
1119                catch (SocketException& e) //Aïe
1120                {
1121                    DeconnecterSocket(i);
1122
1123                    IDLog("Indi_BAO, SocketException IsPoll : ");
1124                    IDLog(e.description().c_str());
1125                    IDLog("\n");
1126                }
1127            }
1128        }
1129
1130
1131        ///////////////////////////////////////
1132        // L'utilisateur a demandé l'annulation du mouvement en cours
1133
1134        if (Abort)
1135        {
1136            // On arrête le suivi d'un objet
1137
1138            Suivi = false;
1139
1140            // On arrête l'enchaînement des actions
1141            // pour réaliser un goto
1142
1143            ActualisationPosition = false;
1144
1145            // On envoie l'ordre ABORT à toutes les antennes
1146
1147            for (int i=1; i<SocketsNumber; i++)
1148            {
1149                if (Sockets[i].Connected)
1150                {
1151                    if (!ABORT(i)) Sockets[i].sendalertes++;
1152                }
1153            }
1154
1155            IDSetSwitch(&OnCoordSetSP, "ABORT OK !");
1156
1157            // Réinititialisation des paramÚtres des antennes
1158
1159            InitAntennes();
1160
1161            //Pour permettre de refaire un abort
1162
1163            Abort=false;
1164        }
1165
1166        ///////////////////////////////////////
1167        // L'utilisateur a demandé de mettre les antennes au repos
1168
1169        if (Park)
1170        {
1171            // On arrête le suivi d'un objet
1172
1173            Suivi = false;
1174
1175            // On arrête l'enchaînement des actions
1176            // pour réaliser un goto
1177
1178            ActualisationPosition = false;
1179
1180            // On envoie l'ordre PARK à toutes les antennes
1181
1182            for (int i=1; i<SocketsNumber; i++)
1183            {
1184                if (Sockets[i].Connected)
1185                {
1186                    if (!PARK(i)) Sockets[i].sendalertes++;
1187                }
1188            }
1189
1190            IDSetSwitch(&OnCoordSetSP, "PARK OK !");
1191
1192            // Réinititialisation des paramÚtres des antennes
1193
1194            InitAntennes();
1195
1196            //Pour permettre de refaire un park
1197
1198            Park=false;
1199        }
1200
1201
1202        ///////////////////////////////////////
1203        // Gestion du suivi
1204
1205        if ((Suivi) && (UpdateGoto))
1206        {
1207            // Délais entre deux actualisations
1208
1209            double delai=ActualisationTM1 / 3600.0 / 24.0;   // Actualisation toutes les 15 minutes en mode transit
1210
1211            if (TrackingMode==2) delai=ActualisationTM2 / 3600.0 / 24.0;   //et 5 secs en mode tracking
1212
1213
1214            // On actualise la position si le delai est dépassé
1215
1216            if (GetJJ() - JJAnc > delai)
1217            {
1218                UpdateGoto = false;
1219
1220                // Conversion des coordonnées en pas moteur
1221
1222                ADDEC2Motor(targetRA, targetDEC);
1223
1224                // On réinitialise les antennes en vue du goto
1225
1226                InitAntennes();
1227
1228                ActualisationPosition = true;
1229
1230                // On sauvegarde la date
1231
1232                JJAnc = GetJJ();
1233            }
1234
1235            //Plus d'antenne ! On arrête le suivi
1236
1237            if (AntennesConnectees() == 0)
1238            {
1239                if ( compt % 1000 == 0)
1240                {
1241                    IDSetSwitch(&OnCoordSetSP, "Erreur ! Plus d antennes connectees !");
1242
1243                    if (Suivi) IDLog("Arrêt du suivi !");
1244
1245                    ActualisationPosition=false;
1246
1247                    Suivi=false;
1248
1249                    InitAntennes();
1250                }
1251            }
1252        }
1253
1254
1255
1256        // Exécution de la procédure complÚte de lecture de la position de l'antenne
1257        // puis envoi d'une commande Goto
1258
1259        if (ActualisationPosition)
1260        {
1261            for (int i=1; i<SocketsNumber; i++)
1262            {
1263                if (Sockets[i].Connected)
1264                {
1265                    switch (Sockets[i].etape)
1266                    {
1267
1268                        //Envoi de la commande POS
1269
1270                    case 0 :
1271                    {
1272                        Sockets[i].ack_pos    = false;
1273                        Sockets[i].PosValides = false;
1274
1275                        if (!POSITION(i)) Sockets[i].sendalertes++;
1276
1277                        Sockets[i].etape++;
1278                    }
1279                    break;
1280
1281
1282                    // A-ton bien reçu l'ack POS ?
1283
1284                    case 1 :
1285                    {
1286                        if (Sockets[i].ack_pos)
1287                        {
1288                            // tout marche bien
1289                            Sockets[i].AttenteExecution = 0;
1290                            Sockets[i].AnomaliesExecution = 0;
1291                            Sockets[i].etape++;
1292                            i--; //permet de revenir sur ce même socket malgré la boucle
1293                            // -> plus rapide
1294                        }
1295                        else
1296                        {
1297                            // on réitÚre l'ordre précédent si rien ne se passe
1298
1299                            // On garde une trace de l'anomalie
1300                            Sockets[i].AttenteExecution++;
1301
1302                            if (Sockets[i].AttenteExecution > MAXATTENTE)
1303                            {
1304                                // on recommence depuis le début
1305                                Sockets[i].etape = 0;
1306                                Sockets[i].AttenteExecution = 0;
1307                                Sockets[i].AnomaliesExecution++;
1308                            }
1309
1310                            // Toujours rien -> plus sérieux : il faut déconnecter l'antenne
1311                            if (Sockets[i].AnomaliesExecution > MAXANOMALIES)
1312                            {
1313                                OnCoordSetSP.s = IPS_ALERT;
1314                                IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : pas d acknowledge recu apres l ordre POSITION. \
1315    Deconnexion de l antenne.", Sockets[i].IP.c_str());
1316                                DeconnecterSocket(i);
1317                            }
1318                        }
1319                    }
1320                    break;
1321
1322
1323                    //Les valeurs retournées pas la commande POSITION sont-elles valides ?
1324
1325                    case 2 :
1326                    {
1327                        if (Sockets[i].PosValides)
1328                        {
1329                            Sockets[i].AttenteExecution = 0;
1330                            Sockets[i].AnomaliesExecution = 0;
1331                            Sockets[i].etape++; // on passe à l'étape suivante
1332                        }
1333                        else
1334                        {
1335                            // on réitÚre l'ordre précédent si rien ne se passe
1336                            Sockets[i].AttenteExecution++;
1337
1338                            if (Sockets[i].AttenteExecution > MAXATTENTE)
1339                            {
1340                                // on attend encore la réponse posvalides                               
1341                                Sockets[i].etape = 2;
1342                                Sockets[i].AttenteExecution = 0;
1343                                Sockets[i].AnomaliesExecution++;
1344                            }
1345
1346                            if (Sockets[i].AnomaliesExecution > MAXANOMALIES)
1347                            {
1348                                OnCoordSetSP.s = IPS_ALERT;
1349                                IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : la position retournee n est pas valide. \
1350    Deconnexion de l antenne.", Sockets[i].IP.c_str());
1351                                DeconnecterSocket(i);
1352                            }
1353                        }
1354                    }
1355                    break;
1356
1357
1358                    // A-ton reçu l'acknowledge de la commande goto ?
1359
1360                    case 4 :
1361                    {
1362                        if (Sockets[i].ack_goto)
1363                        {
1364                            Sockets[i].AttenteExecution = 0;
1365                            Sockets[i].AnomaliesExecution = 0;
1366                            Sockets[i].etape++; // on passe à l'étape suivante
1367                        }
1368                        else
1369                        {
1370                            // on réitÚre l'ordre précédent si rien ne se passe
1371                            Sockets[i].AttenteExecution++;
1372
1373                            if (Sockets[i].AttenteExecution > MAXATTENTE)
1374                            {
1375                                // On prolonge l'attente                               
1376                                Sockets[i].etape = 4;
1377                                Sockets[i].AttenteExecution = 0;
1378                                Sockets[i].AnomaliesExecution++;
1379                            }
1380
1381                            if (Sockets[i].AnomaliesExecution > MAXANOMALIES)
1382                            {
1383                                OnCoordSetSP.s = IPS_ALERT;
1384                                IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : pas d acknowledge recu apres l ordre GOTO. \
1385    Deconnexion de l antenne.", Sockets[i].IP.c_str());
1386                                DeconnecterSocket(i);
1387                            }
1388                        }
1389                    }
1390                    break;
1391
1392
1393                    //  Confirmation goto ok ?
1394
1395                    case 5 :
1396                    {
1397                        if (Sockets[i].GotoOk)
1398                        {
1399                            Sockets[i].AttenteExecution = 0;
1400                            Sockets[i].AnomaliesExecution = 0;
1401                            Sockets[i].etape++;
1402                        }
1403                        else
1404                        {
1405                            // on réitÚre l'ordre précédent si rien ne se passe
1406                            Sockets[i].AttenteExecution++;
1407
1408                            if (Sockets[i].AttenteExecution > MAXATTENTE)
1409                            {
1410                                // On prolonge l'attente
1411                               
1412                                Sockets[i].etape = 5;
1413                                Sockets[i].AttenteExecution = 0;
1414                                Sockets[i].AnomaliesExecution++;
1415                            }
1416
1417                            // On déconnecte l'antenne s'il n'y a pas de coonfirmation du goto au bout de 2 minutes   
1418                            if (Sockets[i].AnomaliesExecution > MAXANOMALIESGOTO)
1419                            {
1420                                OnCoordSetSP.s = IPS_ALERT;
1421                                IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : l antenne n a pas renvoye GOTO/OK. \
1422    Deconnexion de l antenne.", Sockets[i].IP.c_str());
1423                                DeconnecterSocket(i);
1424                            }
1425                        }
1426                    }
1427                    break;
1428                    }
1429                }
1430            }
1431        }
1432
1433
1434        ///////////////////////////////////////
1435        //On attend que toutes les antennes soient prêtes pour lancer l'ordre Goto -> meilleure synchronisation
1436
1437        int num=0;
1438
1439        for (int i=1; i<SocketsNumber; i++)
1440        {
1441            if (Sockets[i].Connected)
1442            {
1443                if (Sockets[i].etape == 3) num++; //fin de la procédure ActualisationPosition.
1444                // num antennes sont prêtes à recevoir l'ordre GOTO
1445            }
1446        }
1447
1448        if ((num == AntennesConnectees()) && (num>0))
1449        {
1450            for (int i=1; i<SocketsNumber; i++ )
1451            {
1452                if (Sockets[i].Connected)
1453                {
1454                    Sockets[i].ack_goto = false;
1455                    Sockets[i].AttenteExecution = 0;
1456                    Sockets[i].AnomaliesExecution = 0;
1457
1458                    if (!GOTO(i, TargetPosition.x - Sockets[i].Pos.x - Sockets[i].Delta.x, TargetPosition.y - Sockets[i].Pos.y - Sockets[i].Delta.y)) Sockets[i].sendalertes++;
1459
1460                    Sockets[i].etape++;
1461                }
1462            }
1463        }
1464
1465        ///////////////////////////////////////
1466        // Détection d'anomalies sur la socket. Déconnexion du micro-cont ?
1467
1468        for (int i=1; i<SocketsNumber; i++)
1469        {
1470            if (Sockets[i].Connected)
1471            {
1472                if (Sockets[i].sendalertes > 0)
1473                {
1474                    OnCoordSetSP.s = IPS_ALERT;
1475                    IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : deconnexion de l antenne.", Sockets[i].IP.c_str());
1476
1477                    DeconnecterSocket(i);
1478                }
1479            }
1480        }
1481    }
1482   
1483    //incrémentation du compteur
1484    compt++;
1485}
1486
1487
1488
1489/**************************************************************************************
1490** Mode transit ou tracking
1491***************************************************************************************/
1492
1493bool BAO::process_coords()
1494{
1495    switch (currentSet)
1496    {
1497        // Transit
1498    case BAO_TRANSIT:
1499
1500        //Eteindre les voyants dans la boîte de dialogue Indi
1501        EquatorialCoordsWNP.s = IPS_BUSY;
1502        AbortSlewSP.s = IPS_IDLE;
1503        ParkSP.s = IPS_IDLE;
1504
1505        IDSetNumber (&EquatorialCoordsWNP, NULL);
1506        IDSetSwitch (&AbortSlewSP, NULL);
1507        IDSetSwitch (&ParkSP, NULL);
1508
1509        // On prépare les antennes pour le prochain goto
1510
1511        InitAntennes();
1512
1513        JJAnc = GetJJ();
1514       
1515        ADDEC2Motor(targetRA, targetDEC);
1516
1517        TrackingMode = 1;
1518
1519        Suivi = true;
1520
1521        UpdateGoto = false;
1522
1523        ActualisationPosition = true;
1524
1525        break;
1526
1527        // Tracking
1528    case BAO_TRACKING:
1529
1530        //Eteindre les voyants dans la boîte de dialogue Indi
1531        EquatorialCoordsWNP.s = IPS_BUSY;
1532        AbortSlewSP.s = IPS_IDLE;
1533        ParkSP.s = IPS_IDLE;
1534
1535        IDSetNumber (&EquatorialCoordsWNP, NULL);
1536        IDSetSwitch (&AbortSlewSP, NULL);
1537        IDSetSwitch (&ParkSP, NULL);
1538
1539        InitAntennes();
1540
1541        JJAnc=GetJJ();
1542       
1543        ADDEC2Motor(targetRA, targetDEC);
1544
1545        TrackingMode = 2;
1546
1547        Suivi = true;
1548
1549        UpdateGoto = false;
1550
1551        ActualisationPosition = true;       
1552
1553        break;
1554    }
1555
1556    return true;
1557}
1558
1559
1560
1561/**************************************************************************************
1562** Connexion / Déconnexion avec le télescope
1563***************************************************************************************/
1564
1565void BAO::connect_telescope()
1566{
1567    switch (ConnectSP.sp[0].s)
1568    {
1569    case ISS_ON:
1570
1571        // Etats des voyants
1572
1573        ConnectS[0].s = ISS_ON;
1574        ConnectS[1].s = ISS_OFF;
1575        ConnectSP.s = IPS_OK;
1576        IDSetSwitch (&ConnectSP, "BAORadio is online. Retrieving basic data...");
1577
1578        // Petit message
1579
1580        IDLog("\nHello BAORadio !\n");
1581
1582        // On lance le thread !
1583
1584        Exit=false;
1585
1586        if (pthread_create (&th1, NULL, (void*(*)(void*))LancementThread, this) < 0)
1587        {
1588            IDLog("pthread_create error for threadSocket\n");
1589        }
1590
1591        break;
1592
1593    case ISS_OFF:
1594
1595        // On sort du thread
1596
1597        Exit = true;
1598        sleep(1);
1599        pthread_join (th1, NULL);
1600        InitThreadOK = false;
1601
1602        // Etat des voyants
1603
1604        ConnectS[0].s = ISS_OFF;
1605        ConnectS[1].s = ISS_ON;
1606        ConnectSP.s = IPS_IDLE;
1607        IDSetSwitch (&ConnectSP, "BAORadio is offline.");
1608        IDLog("Telescope is offline.");
1609
1610        // On déconnecte tous les sockets
1611
1612        for (int i=0; i<MAXHOSTNAME; i++)
1613        {
1614            DeconnecterSocket(i);
1615        }
1616
1617        // init
1618
1619        InitAntennes();
1620
1621        SocketsNumber = 1;
1622
1623        break;
1624    }
1625}
1626
1627
1628
1629
1630/**************************************************************************************
1631**  Envoie une commande sur le socket numsocket
1632***************************************************************************************/
1633
1634bool BAO::COMMANDE(int numsocket, char* Commande, char* Params)
1635{
1636    char chaine[MAXCARACTERES];
1637
1638    try
1639    {
1640        sprintf(chaine, "%s%s\n", Commande, Params);
1641       
1642        Sockets[numsocket].new_sock << chaine;
1643       
1644        IDLog("Commande envoyee a %s: %s", Sockets[numsocket].IP.c_str(), chaine);
1645    }
1646    catch (SocketException& e)
1647    {
1648        DeconnecterSocket(numsocket);
1649
1650        IDLog("Indi_BAO, COMMANDE exception : ");
1651        IDLog(e.description().c_str());
1652        IDLog("\n");
1653
1654        return false;
1655    }
1656
1657    return true;
1658}
1659
1660
1661/**************************************************************************************
1662** Commande POSITION
1663***************************************************************************************/
1664
1665bool BAO::POSITION(int numsocket)
1666{
1667    return COMMANDE(numsocket, (char*)"P", (char*)"");
1668}
1669
1670/**************************************************************************************
1671** Commande PARK
1672***************************************************************************************/
1673
1674bool BAO::PARK(int numsocket)
1675{
1676    return COMMANDE(numsocket, (char*)"Z", (char*)"");
1677}
1678
1679/**************************************************************************************
1680** Commande ABORT
1681***************************************************************************************/
1682
1683bool BAO::ABORT(int numsocket)
1684{
1685    return COMMANDE(numsocket, (char*)"A", (char*)"");
1686}
1687
1688
1689/**************************************************************************************
1690** Commande GOTO
1691***************************************************************************************/
1692
1693bool BAO::GOTO(int numsocket, int deltaAz, int deltaAlt)
1694{
1695    char Params[MAXCARACTERES];
1696    char sensAz;
1697    char sensAlt;
1698
1699    sensAlt = 1;
1700    sensAz  = 1;
1701
1702    if ( deltaAz < 0 )
1703    {
1704        deltaAz = -deltaAz;
1705        sensAz  = 0;
1706    }
1707
1708    if ( deltaAlt < 0 )
1709    {
1710        deltaAlt = -deltaAlt;
1711        sensAlt  = 0;
1712    }
1713
1714    // Vérification du nombre de pas à faire au niveau de l'axe azimut
1715    // Rappel : un tour complet autour de l'axe az fait 4000 pas codeur (#define NBREPASCODEURSAZ dans BAO.h)
1716
1717    // problÚme 1 : si deltaAz > à un demi-tours - soit 2000 pas alors
1718    // on fait le trajet dans le sens inverse pour aller plus vite
1719
1720    // problÚme 2 : Passage au méridien
1721    // on se situe à quelques secondes de degrés avant le sud par exemple (nb de pas 3995 par exemple)
1722    // et on franchit le méridien (nb de pas codeur = 5 par exemple)
1723    // On risque alors de faire un tour complet en sens inverse pour rattraper l'objet -> à éviter
1724
1725    // ne pas faire des tours complets en Az pour rien...
1726    while (deltaAz > NBREPASCODEURSAZ) deltaAz -= NBREPASCODEURSAZ;
1727
1728    // Doit résoudre tous les problÚmes concernant l'azimut...
1729    if (deltaAz > NBREPASCODEURSAZ / 2 )
1730    {
1731        deltaAz = NBREPASCODEURSAZ - deltaAz;
1732        sensAz = 1 - sensAz;
1733    }
1734
1735    //on envoie les coordonnées au driver
1736
1737    if (sensAz == 1 )  sensAz='f'; else sensAz='b';
1738   
1739    if (sensAlt == 1 ) sensAlt='f'; else sensAlt='b';
1740
1741    sprintf(Params, "%c%04i%c%04i", sensAz, deltaAz, sensAlt, deltaAlt);
1742
1743    return COMMANDE(numsocket, (char*)"G", Params);
1744}
1745
1746
1747
1748/**************************************************************************************
1749** Les fonctions qui suivent sont nécessaires pour construire le pilote Indi_BAO
1750** Elles sont appelées par le noyau d'Indi
1751***************************************************************************************/
1752
1753/**************************************************************************************
1754** Initialisation du pilote BAO
1755***************************************************************************************/
1756
1757void ISInit()
1758{
1759    //Il ne faut exécuter la fonction qu'une seule fois
1760    static int isInit = 0;
1761
1762    if (isInit) return;
1763
1764    if (telescope.get() == 0) telescope.reset(new BAO());
1765
1766    isInit = 1;
1767
1768    //initialisation du timer
1769
1770    IEAddTimer (POLLMS, ISPoll, NULL);
1771}
1772
1773
1774void ISGetProperties (const char *dev)
1775{
1776    ISInit();
1777
1778    telescope->ISGetProperties(dev);
1779}
1780
1781void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
1782{
1783    ISInit();
1784    telescope->ISNewSwitch(dev, name, states, names, n);
1785}
1786
1787void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
1788{
1789    ISInit();
1790    telescope->ISNewText(dev, name, texts, names, n);
1791}
1792
1793void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
1794{
1795    ISInit();
1796    telescope->ISNewNumber(dev, name, values, names, n);
1797}
1798
1799void ISNewBLOB (const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
1800{
1801    INDI_UNUSED(dev);
1802    INDI_UNUSED(name);
1803    INDI_UNUSED(sizes);
1804    INDI_UNUSED(blobsizes);
1805    INDI_UNUSED(blobs);
1806    INDI_UNUSED(formats);
1807    INDI_UNUSED(names);
1808    INDI_UNUSED(n);
1809}
1810
1811void ISSnoopDevice (XMLEle *root)
1812{
1813    INDI_UNUSED(root);
1814}
1815
1816void ISPoll (void *p)
1817{
1818    INDI_UNUSED(p);
1819
1820    telescope->ISPoll();
1821
1822    IEAddTimer (POLLMS, ISPoll, NULL);
1823}
1824
1825
1826/**************************************************************************************
1827**
1828***************************************************************************************/
1829
1830int BAO::get_switch_index(ISwitchVectorProperty *sp)
1831{
1832    for (int i=0; i < sp->nsp ; i++)
1833        if (sp->sp[i].s == ISS_ON)
1834            return i;
1835
1836    return -1;
1837}
1838
1839
1840/**************************************************************************************
1841**
1842***************************************************************************************/
1843void BAO::get_initial_data()
1844{
1845    //  IDSetNumber (&EquatorialCoordsRNP, NULL);
1846}
1847
1848/**************************************************************************************
1849**
1850***************************************************************************************/
1851void BAO::slew_error(int slewCode)
1852{
1853    OnCoordSetSP.s = IPS_IDLE;
1854
1855    if (slewCode == 1)
1856        IDSetSwitch (&OnCoordSetSP, "Object below horizon.");
1857    else if (slewCode == 2)
1858        IDSetSwitch (&OnCoordSetSP, "Object below the minimum elevation limit.");
1859    else
1860        IDSetSwitch (&OnCoordSetSP, "Slew failed.");
1861}
1862
1863/**************************************************************************************
1864**
1865***************************************************************************************/
1866
1867bool BAO::is_connected()
1868{
1869    // return (ConnectSP.sp[0].s == ISS_ON);
1870    return (ConnectSP.s == IPS_OK);
1871}
1872
1873/**************************************************************************************
1874**
1875***************************************************************************************/
1876void BAO::connection_lost()
1877{
1878    ConnectSP.s = IPS_IDLE;
1879    IDSetSwitch(&ConnectSP, "The connection to the telescope is lost.");
1880    IDLog("arret");
1881    return;
1882}
1883
1884/**************************************************************************************
1885**
1886***************************************************************************************/
1887void BAO::connection_resumed()
1888{
1889    ConnectS[0].s = ISS_ON;
1890    ConnectS[1].s = ISS_OFF;
1891    ConnectSP.s = IPS_OK;
1892
1893    IDSetSwitch(&ConnectSP, "The connection to the telescope has been resumed.");
1894}
1895
1896
1897/**************************************************************************************
1898** GÚre les erreurs de communication avec la boîte Indi
1899***************************************************************************************/
1900/*
1901void BAO::handle_error(INumberVectorProperty *nvp, int err, const char *msg)
1902{
1903    nvp->s = IPS_ALERT;
1904
1905    // If the error is a time out, then the device doesn't support this property
1906    if (err == -2)
1907    {
1908        nvp->s = IPS_ALERT;
1909        IDSetNumber(nvp, "Device timed out. Current device may be busy or does not support %s. Will retry again.", msg);
1910    }
1911    else
1912        // Changing property failed, user should retry.
1913        IDSetNumber( nvp , "%s failed.", msg);
1914
1915    fault = true;
1916}*/
1917
1918
1919/**************************************************************************************
1920**
1921***************************************************************************************/
1922/*
1923void BAO::correct_fault()
1924{
1925    fault = false;
1926    IDMessage(mydev, "Telescope is online.");
1927}*/
1928
1929
1930
Note: See TracBrowser for help on using the repository browser.