source: BAORadio/libindi/libindi/BAOcontrol/baocontrol.cpp @ 697

Last change on this file since 697 was 697, checked in by frichard, 12 years ago

-Passage de la version 0.9 à la version 0.9.5 de la biliothèque libindi
-correction d'un bug affectant la commande 'm'
-vérification des fuites de mémoire et débogage complet

File size: 92.9 KB
Line 
1/******************************/
2/* BAOCONTROL                 */
3/*                            */
4/* Franck RICHARD             */
5/* franckrichard033@gmail.com */
6/* Février 2012               */
7/******************************/
8
9
10#include "baocontrol.h"
11
12
13
14/**************************************************************************************
15** Constructeur de la classe BAOcontrol
16**
17***************************************************************************************/
18
19BAOcontrol::BAOcontrol()
20{
21    float a1, a2, a3;
22
23    char *Version;
24
25    // Le choix de la couleur des caractÚres est adapté pour une fenêtre de terminal
26    // ayant un fond blanc. pour un fond noir, mettre couleurs = 2 dans le fichier params
27
28    ChoixCouleurs=1;
29
30    // Affichage de la version du programme
31
32    Version = new char[1000];
33
34    sprintf(Version,"\n\n\n\n\n \
35 ******************************************\n \
36 *             BAORadio Control           *\n \
37 * Laboratoire de l'Accélérateur Linéaire *\n \
38 *                                        *\n \
39 *             v%s   %s           *\n \
40 *        franckrichard033@gmail.com      *\n \
41 ******************************************\n\n\n", VERSION, VERSION_DATE);
42
43    AfficherLog(Version, true);
44
45    delete [] Version;
46
47
48    // Initialisation des variables globales et des pointeurs
49    // pour la signification des variables, voir baocontrol.h
50
51    //BAOcontrol
52
53    delaitransit           = 0;
54    delaitracking          = 0;
55    lognum                 = 0;
56    numAntennes            = 0;
57    numobjets              = 0;
58    numEtoiles             = 0;
59    runnum                 = 1;
60
61    MethodeAlignement      = SIMPLE;
62
63    Pression               = 1013.0;
64    Temperature            = 10.0;
65
66    NoExit                 = true;
67    Transit                = false;
68    run                    = false;
69    exitrun                = false;
70    ModificationAlignement = false;
71
72    fd                     = NULL;
73    client_socket          = NULL;
74
75    // chaînes de caractÚres et tableaux
76
77    LatitudeChar           = "";
78    LongitudeChar          = "";
79    Serveur                = "";
80    Port                   = "";
81    chaineDateHeure[0]     = 0;
82
83    Antennes               = new DefAntenne[ MAXANTENNES ];
84    objets                 = new DefObjets [ MAXOBJETS ];
85    Etoiles                = new DefEtoiles[ MAXETOILES];
86
87
88    // on initialise aussi les structures
89
90    for (int i=0; i<MAXANTENNES; i++)
91    {
92        Antennes[i].ok = 0;
93        Antennes[i].ip = 0;
94
95        Antennes[i].AlignementAntenne = new Alignement();
96    }
97
98    for (int i=0; i<MAXOBJETS; i++)
99    {
100        objets[i].JJ   = 0.0;
101        objets[i].exec = false;
102    }
103
104    for (int i=0; i<MAXETOILES; i++)
105    {
106        Etoiles[i].nom          = "";
107        Etoiles[i].ad           = 0.0;
108        Etoiles[i].de           = 0.0;
109        Etoiles[i].az           = 0.0;
110        Etoiles[i].ha           = 0.0;
111        Etoiles[i].mag          = 0.0;
112        Etoiles[i].selectionnee = false;
113    }
114
115
116    // Chargement du fichier contenant les paramÚtres de l'application BAOcontrol
117    // La variable permet de récupérer le nom de l'utilisateur ayant ouvert la session sous linux
118    // c'est dans le répertoire /home/USER/ que BAOcontrol cherche le fichier de paramÚtre baocontrol_params
119
120    if (!ChargementParametres("/home/" + (string)getenv("USER") + "/baocontrol_params"))
121    {
122        ErreurLog("Le fichier de configuration 'params' contient des erreurs ou n'existe pas.\n");
123        ErreurLog("Il devrait se trouver dans le répertoire /home/" + (string)getenv("USER") +"\n");
124        ErreurLog("Merci de vérifier...\n\n");
125        exit(1);
126    }
127
128
129    // Conversion de la latitude et de la longitude en radians
130
131    Decomposition(LatitudeChar, 0, &a1, &a2, &a3);
132
133    double Latitude = (a1 + a2 / 60.0 + a3 / 3600.0) * Pidiv180;
134
135    Decomposition(LongitudeChar, 1, &a1, &a2, &a3);
136
137    double Longitude = Pi2 - ( a1 + a2 / 60.0 + a3 / 3600.0 ) * Pidiv180;
138
139
140    /*
141        Latitude=(48.0+41.0/60.0+58.0/3600.0)*Pidiv180;
142        Longitude = -(2.0+10.0/60.0+18.0/3600.0)*Pidiv180;
143        Pression=0.0;
144    */
145
146
147    // Transfert de la latitude, longitude, pression, température à la classe Astro
148
149    DefinirLongitudeLatitude(Longitude, Latitude);
150
151    DefinirPressionTemp(Pression, Temperature);
152
153
154
155    //DefinirDateHeure(2012.0, 6.0, 29.0, 22.0, 39.0, 40.0);
156    //DefinirDateHeure(2012.0, 6.0, 29.0, 22.0, 49.0, 18.0);
157    //DefinirDateHeure(2012.0, 6.0, 29.0, 22.0, 57.0, 52.0);
158    //DefinirDateHeure(2012.0, 6.0, 29.0, 20.0, 59.0, 8.0);
159    //DefinirDateHeure(2012.0, 6.0, 29.0, 21.0, 55.0, 57.0);
160
161
162
163    // On lance les calculs (Temps sidéral local etc...)
164
165    CalculTSL();
166
167    /*
168    double a, b, c,d, a22, b22, c22, d22;
169    double e,f;
170    stringstream os;
171
172    os << "tsl=" << DHMS(GetTSL()*N180divPi, true)<< "  " << GetTSL() << "\n";
173
174    AfficherLog(os.str(), true);
175    os.str("");
176
177    a=15.0*(18.0+36.0/60.0+56.3/3600.0)*Pidiv180;
178    b=(38.0+47.0/60.0+3.1/3600.0)*Pidiv180;
179
180    a= 3.61082;
181    b=0.860677;
182    a22=3.39278;
183    b22=0.844504;
184
185    a= 4.87356;
186    b=0.676912;
187    a22=4.94645;
188    b22=0.577727;
189
190    a= 5.41677;
191    b=0.790291;
192    a22=5.55106;
193    b22=0.699053;
194
195    a=4.87356;
196    b=0.676912;
197    a22=4.97375;
198    b22=0.579795;
199
200
201    a=3.73351;
202    b=0.334748;
203    a22=3.61661;
204    b22=0.241758;
205
206
207    //a=15.0*(18.0+37.0/60.0+22.0/3600.0)*Pidiv180;
208    //b=(38.0+47.0/60.0+43.0/3600.0)*Pidiv180;
209
210    //CoordonneesHorairesDouble Soleil;
211
212    //CalculARDecSoleil(&Soleil);
213
214    //a=Soleil.ar;
215    //b=Soleil.dec;
216    //Precession(&a, &b);
217    //NutationEtoile(&a, &b);
218
219    //AberrationAnnuelle(&a, &b);
220
221    os << "ad=" << DHMS(a*N180divPi, true) << "   de=" << DHMS(b*N180divPi, false) << "\n";
222    os << "ad=" << a << "   de=" << b  << "\n";
223
224    Alignement *al;
225
226    al=new Alignement();
227
228    Azimut(a, b, &c, &d);
229    Azimut(a22, b22, &c22, &d22);
230
231    double ec1 = (c-c22)/PasDeltaAz;
232    double ec2=  (d-d22)/PasDeltaHa;
233
234    os << "nb de pas   az=" << ec1 << "  ha=" << ec2 << "\n";
235
236    double c3= VerifAngle((c * N180divPi * 4000.0/360.0 + ec1) * (360.0 / 4000.0) * Pidiv180 );
237
238    double   d3 = al->Motor2Alt(al->Alt2Motor(d * N180divPi) + ec2) * Pidiv180;
239
240    double sp=DistanceAngulaireEntre2Points(c, d, c3, d3) *N180divPi;
241
242    os << "sep=" << sp << "°    dist haut=" << (d-d3)*N180divPi <<"\n";
243
244    AzHa2ADDe(c3, d3, &a, &b);
245
246    os << "ad=" << DHMS(a*N180divPi, true) << "   de=" << DHMS(b*N180divPi, false) << "\n";
247    os << "ad=" << a << "   de=" << b  << "\n";
248
249    AfficherLog(os.str(), true);
250
251    Azimut(a,b,&c,&d);
252
253    os.str("");
254
255    os << "az=" << DHMS(c*N180divPi, false)<< "   ha=" << DHMS(d*N180divPi, false) << "\n";
256
257    delete al;
258
259    AfficherLog(os.str(), true);
260    */
261
262
263
264
265    //Chargement du catalogue d'étoiles que l'on utilise pour l'alignement des antennes
266
267    if ( !ChargementCatalogueEtoiles("/home/" + (string)getenv("USER") + "/bao_catalogue.dat") )
268    {
269        ErreurLog("Le catalogue d'étoiles 'bao_catalogue' est introuvable.\n");
270        ErreurLog("Il devrait se trouver dans le répertoire /home/" + (string)getenv("USER") +"\n");
271        ErreurLog("Merci de vérifier...\n\n");
272        exit(1);
273    }
274
275
276    // Ouverture du socket avec indi_BAO
277
278    client_socket = new ClientSocket("localhost", atoi(Port.c_str()) );
279
280    // On se connecte au pilote indi_BAO
281
282    Connect(true);
283
284}
285
286
287
288/**************************************************************************************
289** Destructeur de la classe BAOcontrol
290**
291***************************************************************************************/
292
293BAOcontrol::~BAOcontrol()
294{
295
296    AfficherLog("\nNettoyage de la mémoire...\n\n", true);
297
298    // destruction des pointeurs et des tableaux
299
300    for (int i=0; i<MAXANTENNES; i++)
301    {
302        delete Antennes[i].AlignementAntenne;
303    }
304
305    delete [] Antennes;
306    delete [] objets;
307    delete [] Etoiles;
308
309
310    // destruction du socket
311
312    delete client_socket;
313}
314
315
316
317/**************************************************************************************
318** Dessine les éléments dans la fenêtre graphique
319**
320***************************************************************************************/
321
322void BAOcontrol::Dessiner()
323{
324    // On récupÚre la date et l'heure contenue dans la classe astro (ainsi que le jour julien)
325
326    double h  = GetHeure();
327    double mi = GetMin();
328    double s  = GetSec();
329    double a  = GetAnnee();
330    double m  = GetMois();
331    double j  = GetJour();
332    double JJ = GetJJ();
333
334
335    // on évite les affichages de l'heure du genre 12:56:60 ou 24:00:00
336
337    if (s == 60) {
338        s = 0;
339        mi++;
340        if (mi == 60) {
341            mi = 0;
342            h++;
343            if (h == 24) {
344                h = 0;
345                j++;
346            }
347        }
348    }
349
350    //affichage de la date et de l'heure
351
352    sprintf(chaineDateHeure, "%02.0f:%02.0f:%02.0f TU    %02.0f/%02.0f/%04.0f    JJ=%10.5f    Tsl=%s",
353            h, mi, s, j, m, a, JJ, DHMS(GetTSL()*N180divPi, true).c_str());
354
355
356
357    // En cas d'exécution d'un fichier de mouvements, on affiche la durée avant la prochaine étape
358
359    if (run)
360    {
361//       sprintf(chaine, "Prochaine etape dans %4.1fs", (objets[runnum].JJ - JJ) * 3600.0 * 24.0);
362
363    }
364}
365
366
367
368/**************************************************************************************
369** RécupÚre les messages envoyés par le serveur indi_BAO
370**
371***************************************************************************************/
372
373void BAOcontrol::LireReponse()
374{
375    string reponse, memreponse, decomp;
376
377    bool test = false;
378
379    // on récupÚre les messages provenant d'indi_BAO
380
381    *client_socket >> reponse;
382
383    do
384    {
385        // s'il contient le mot message (et vient donc d'indi_BAO)
386
387        if (reponse.find("message") != string::npos)
388        {
389            // On ne garde que la partie intéressante
390            // La partie qui suit "message="...
391
392            reponse = reponse.substr(reponse.find("message") + 9);
393
394            // (on en garde une trace)
395
396            memreponse = reponse;
397
398            // ...on extrait le message jusqu'au caractÚre "
399
400            reponse = reponse.substr(0, reponse.find("\""));
401
402            // On récupÚre l'adresse ip de l'antenne qui nous parle
403            // et on met à jour le tableau des états de l'antenne correspondante
404            // Dans les messages d'indi_BAO, l'adresse ip précÚde les mots "Antennes connectées"
405
406            if (reponse.find(" (Antennes connectees")!=string::npos)
407            {
408                decomp = reponse.substr(0, reponse.find(" (Antennes connectees"));
409                decomp = decomp.substr(decomp.rfind(".")+1);
410
411                // si cette antenne est déjà connectée, on change son état si nécessaire
412
413                if ( atoi(decomp.c_str()) != 0 ) for (int i=0; i<numAntennes; i++)
414                    {
415                        // on a trouvé l'antenne correspondante
416
417                        if (atoi(decomp.c_str()) == Antennes[i].ip)
418                        {
419                            Antennes[i].ok = 1;
420                            test = true;
421                            break;
422                        }
423                    }
424
425                // ou si c'est une nouvelle antenne, on l'ajoute au tableau Antennes
426
427                if (!test)
428                {
429                    Antennes[numAntennes].ip = atoi(decomp.c_str());
430
431                    Antennes[numAntennes++].ok = 1;
432                }
433            }
434
435            // erreur sur une antenne -> on change son état dans la fenêtre
436            // on trouve les erreurs dans les messages d'indi_BAO formulée
437            // de la façon suivante: "ALERTE antenne" ou bien "Erreur sur l antenne"
438
439            if  ((reponse.find("ALERTE antenne ") != string::npos) ||
440                    (reponse.find("Erreur sur l antenne ") != string::npos))
441            {
442                decomp = reponse.substr(0, reponse.find(" :"));
443                decomp = decomp.substr(decomp.rfind(".") + 1);
444
445                for (int i=0; i<numAntennes; i++)
446                {
447                    // On identifie l'antenne dans le tableau Antennes et on change son état
448
449                    if (atoi(decomp.c_str()) == Antennes[i].ip)
450                    {
451                        Antennes[i].ok = 2;  // Erreur sur l'antenne i
452                    }
453                }
454            }
455
456            // On sauvegarde le message dans le fichier logs mais on ne l'affiche pas
457
458            stringstream os;
459
460            os << lognum << " : " << reponse;
461
462            AfficherLog(os.str() + "\n", false);
463
464            if ( lognum < MAXLOG - 1 ) logs[ lognum++ ] = os.str();
465
466            reponse = memreponse;
467        }
468        else reponse = "";
469
470
471    } while ( reponse != "" );
472
473    // on actualise la fenêtre
474
475    Dessiner();
476
477}
478
479
480
481/**************************************************************************************
482** Est-ce que la réponse du pilote indi_BAO est conforme à ce que l'on attendait ?
483**
484**
485***************************************************************************************/
486
487bool BAOcontrol::VerifReponse(string reponseattendue, string *retourreponse)
488{
489    string reponse = "";
490    string memreponse = "";
491    int    duree = 0;
492    bool   test = false;
493
494
495    // TODO :La réponse du driver ne vient pas tout de suite et on peut recevoir
496    // des messages intermédiaires un peu étranges impliquant la fonction CONNECT, pourquoi ?
497    // Là on lit les messages cinq fois de suite pour essayer de voir passer le bon
498    // Essayer de voir si on ne peut pas faire mieux...
499
500    if (retourreponse) *retourreponse = "";
501
502    for (int i=0; i<5 ; i++)
503    {
504        do
505        {
506            usleep(1000); // attendre 1 ms pour laisser le temps au pilote indi_BAO de répondre
507
508            *client_socket >> reponse;
509
510            duree++;
511        }
512        while (reponse.length() == 0 && duree < MAX_DELAI_REPONSE ); // on attend un message pendant 10 ms max
513
514        // on ajoute tous les messages reçus dans memmreponse
515        // ->intéressant pour le debug
516
517        memreponse += reponse;
518
519        if (reponse.find(reponseattendue) != string::npos)
520        {
521            test = true;
522            break;
523        }
524    }
525
526
527    if (!test)
528    {
529        // réponse inconnue -> une erreur ?
530
531        size_t pos = memreponse.find("message=");
532
533        if ( pos != string::npos )
534        {
535            memreponse = memreponse.substr(pos + 9);
536
537            memreponse = memreponse.substr(0, memreponse.find("\""));
538        }
539
540        if (memreponse != "")  ErreurLog("Réponse du pilote indi_BAO :" + memreponse + "\n\n");
541
542        return false;
543    }
544
545    if (retourreponse)
546    {
547        size_t pos = memreponse.find(reponseattendue);
548
549        if ( pos != string::npos )
550        {
551            memreponse = memreponse.substr(pos);
552
553            memreponse = memreponse.substr(0, memreponse.find("\""));
554        }
555
556        *retourreponse = memreponse;
557    }
558
559    return true;
560}
561
562
563
564/**************************************************************************************
565** Calcul du jour julien et du temps sidéral local
566**
567***************************************************************************************/
568
569void BAOcontrol::UpdateTime()
570{
571    time_t t;
572    struct tm date;
573    struct timeval tv;
574
575    // On récupÚre la date et l'heure depuis l'horloge du systÚme
576
577    time(&t);
578    date=*gmtime(&t);
579    gettimeofday(&tv, NULL);
580
581    double Annee = (double)date.tm_year + 1900.0;
582    double Mois  = (double)date.tm_mon + 1.0;
583    double Jour  = (double)date.tm_mday;
584    double Heu   = (double)date.tm_hour;
585    double Min   = (double)date.tm_min;
586    double Sec   = (double)date.tm_sec + tv.tv_usec / 1.0E6;
587    //double UTCP  = 0.0;//(double)date.tm_isdst;
588
589    // On actualise la date et l'heure dans la classe Astro
590
591    DefinirDateHeure(Annee, Mois, Jour, Heu, Min, Sec);
592
593    // On lance les calculs (Temps sidéral local etc...)
594
595    CalculTSL();
596}
597
598
599
600/**************************************************************************************
601** gestion du thread permettant
602** - l'exécution d'une liste de mouvements programmés
603** - l'actualisation de la fenêtre graphique
604** - la récupération des messages du pilote indi_BAO
605**
606***************************************************************************************/
607
608void BAOcontrol::thread_process ()
609{
610    stringstream os;
611   // struct timeval tv;
612
613
614    // On actualise le jour julien et le temps sidéral local
615
616    UpdateTime();
617
618    // On récupÚre le jour julien
619
620    double JJ = GetJJ();
621
622    // Faut-il exécuter un fichier de mouvements ?
623
624    if (run && numobjets > 1 && runnum < numobjets)
625    {
626        // On lance le mouvement numéro runnum si la date et l'heure correspondent au début
627        // de son exécution et que ce mouvement n'a pas été encore réalisé
628
629        if ( JJ >= objets[runnum].JJ && !objets[runnum].exec )
630        {
631            // petit message pour l'utilisateur au début de l'exécution du tout premier mouvement
632
633            if ( runnum == 1 ) AfficherLog("Début de l'exécution du fichier de mouvements\n\n", true);
634
635            os << "Suivi de l'objet n°" << runnum << endl;
636
637            AfficherLog(&os, true);
638
639            // on note que le mouvement est en cours d'exécution
640            // ou qu'il a été déjà exécuté
641
642            objets[runnum].exec = true;
643
644            // on pointe l'objet correspondant
645
646            Goto( objets[runnum].ad, objets[runnum].de, Transit, J2000 );
647        }
648
649
650        // On arrive à la fin de l'exécution du mouvements runnum
651
652        if (JJ >= objets[runnum].JJ + objets[runnum].Duree / 3600.0 / 24.0 )
653        {
654            // On interrompt le mouvement
655
656            Abort();
657
658            // S'il s'agit du dernier mouvement -> Fin de la commande run
659
660            if ( runnum + 1 >= numobjets )
661            {
662                AfficherLog("Fin de l'execution du fichier de mouvements\n\n", true);
663
664                // on réaffiche le prompt
665
666                cout << endl;
667                ChoixCouleurs==1 ? cout << blue1 : cout << blue2;
668                cout << ">";
669
670                // on réinitialise toutes les variables impliquées dans la commande run
671
672                run             = false;
673                runnum  = 1;
674                numobjets       = 1;
675
676                // On sort du programme dans le cas de BAOControl -r fileName
677
678                NoExit = !exitrun;
679            }
680            else
681            {
682                // on passe au mouvement suivant
683
684                runnum++;
685            }
686        }
687    }
688
689    // on lit et affiche la réponse des micro-contrÃŽleurs
690
691    LireReponse();
692
693    // pause de 100 ms
694
695    // usleep(100000);
696
697}
698
699
700
701
702
703
704/**************************************************************************************
705** Décrypte les commandes saisies par l'utilisateur
706** Exemples :
707** DecompositionCommande("goto 10:10:10 25:10:10", "goto", &chaine1, &chaine2)
708** retourne chaine1  = "10:10:10"
709**          chaine2  = "25:10:10"
710**
711** DecompositionCommande("goto messier 1","goto", &chaine1, NULL) (avec chaine2=NULL)
712** retourne chaine1  = "messier 1"
713**          chaine2  = NULL
714**
715***************************************************************************************/
716
717bool BAOcontrol::DecompositionCommande(string chaine, string commande, string *chaine1, string *chaine2)
718{
719    size_t pos = chaine.find(commande);
720
721    // si la commande est présente dans chaîne, on continue
722
723    if (pos != string::npos)
724    {
725        // on s'intéresse aux caractÚres qui suivent la commande
726
727        pos += commande.length();
728
729        chaine = chaine.substr(pos);
730
731        // on ignore les espaces superflus
732
733        while (chaine[0] == ' ') chaine = chaine.substr(1);
734
735        // si on veut prendre les deux arguments d'une commande
736
737        if (chaine2 != NULL)
738        {
739            // on prend le premier bloc jusqu'au prochain espace -> c'est la chaine1
740
741            *chaine1 = chaine.substr(0, chaine.find(" "));
742
743            // puis on prend le deuxiÚme bloc -> c'est la chaine2
744
745            pos = chaine.find(" ");
746
747            if (pos != string::npos)
748            {
749                chaine = chaine.substr(pos + 1);
750
751                while (chaine[0] == ' ') chaine = chaine.substr(1);
752
753                *chaine2 = chaine.substr(0, chaine.find(" "));
754            }
755        }
756        else
757        {
758            // on prend tout d'un bloc aprÚs la commande -> chaine 1
759            // utile pour une commande du type "goto m 42" qui doit retourner "m 42" dans une
760            // même chaîne
761
762            *chaine1 = chaine;
763        }
764    } else return false;
765
766    return true;
767}
768
769
770
771/**************************************************************************************
772** Envoie la longitude et la latitude du lieu d'observation au pilote indi_BAO
773** sous la forme de vecteurs xml
774** (voir les particularités des drivers développés sous Indi)
775**
776***************************************************************************************/
777
778bool BAOcontrol::EnvoyerCoordGeographiques()
779{
780    // la communication avec le pilote indi_BAO
781    // se fait par l'envoi de trames au format xml
782
783    try
784    {
785        *client_socket << "<newNumberVector device=\"BAO\" name=\"GEOGRAPHIC_COORD\">";
786        *client_socket << "<oneNumber name=\"LAT\">";
787        *client_socket << LatitudeChar;
788        *client_socket << "</oneNumber>";
789        *client_socket << "<oneNumber name=\"LONG\">";
790        *client_socket << LongitudeChar;
791        *client_socket << "</oneNumber>";
792        *client_socket << "</newNumberVector>";
793
794        if (!VerifReponse("name=\"GEOGRAPHIC_COORD\" state=\"Ok\"", NULL))
795        {
796            ErreurLog("ERREUR fct EnvoyerCoordGeographiques : pas de réponse du pilote indi_BAO.\n\n");
797
798            return false;
799        }
800    }
801
802    // un problÚme ?
803
804    catch ( SocketException& e )
805    {
806        ErreurLog("Exception was caught:" + e.description() + "\n");
807
808        return false;
809    }
810
811    AfficherLog("Les coordonnées géographiques ont bien été envoyées au pilote indi_BAO\n\n", true);
812
813    return true;
814}
815
816
817/**************************************************************************************
818** Transmet la pression et la température au pilote indi_BAO
819**
820***************************************************************************************/
821
822bool BAOcontrol::EnvoyerPressionTemperature()
823{
824    stringstream os;
825
826    try
827    {
828        *client_socket << "<newNumberVector device=\"BAO\" name=\"PRESSION_DATA\">";
829        *client_socket << "<oneNumber name=\"Pression\">";
830        os << Pression;
831        *client_socket << os.str();
832        os.str("");
833        *client_socket << "</oneNumber>";
834        *client_socket << "<oneNumber name=\"Temperature\">";
835        os << Temperature;
836        *client_socket << os.str();
837        os.str("");
838        *client_socket << "</oneNumber>";
839        *client_socket << "</newNumberVector>";
840
841        if (!VerifReponse("name=\"PRESSION_DATA\" state=\"Ok\"", NULL))
842        {
843            ErreurLog("ERREUR fct EnvoyerPressionTemperature : pas de réponse du pilote indi_BAO.\n\n");
844
845            return false;
846        }
847    }
848
849    // un problÚme ?
850
851    catch ( SocketException& e )
852    {
853        ErreurLog("Exception was caught:" + e.description() + "\n");
854
855        return false;
856    }
857
858    AfficherLog("La pression et la température ont bien été envoyées au pilote indi_BAO\n\n", true);
859
860    return true;
861}
862
863/**************************************************************************************
864** Envoie les paramÚtres delaitransit et delaitracking au pilote indi_BAO
865** Ces paramÚtres définissent la durée (en sec) entre deux actualisations
866** dans les modes tracking et transit
867**
868***************************************************************************************/
869
870bool BAOcontrol::EnvoyerDelaisModesTransitEtTracking()
871{
872    stringstream os;
873
874    try
875    {
876        os << delaitransit;
877        *client_socket << "<newNumberVector device=\"BAO\" name=\"DELAY1\">";
878        *client_socket << "<oneNumber name=\"DELAY\">";
879        *client_socket << os.str();
880        *client_socket << "</oneNumber>";
881        *client_socket << "</newNumberVector>";
882        os.str("");
883
884        if (!VerifReponse("name=\"DELAY1\" state=\"Ok\"", NULL))
885        {
886            ErreurLog("ERREUR fct EnvoyerDelaisModesTransitEtTracking : pas de réponse du pilote indi_BAO.\n\n");
887
888            return false;
889        }
890
891        os << delaitracking;
892        *client_socket << "<newNumberVector device=\"BAO\" name=\"DELAY2\">";
893        *client_socket << "<oneNumber name=\"DELAY\">";
894        *client_socket << os.str();
895        *client_socket << "</oneNumber>";
896        *client_socket << "</newNumberVector>";
897        os.str("");
898
899        if (!VerifReponse("name=\"DELAY2\" state=\"Ok\"", NULL))
900        {
901            ErreurLog("ERREUR fct EnvoyerDelaisModesTransitEtTracking : pas de réponse du pilote indi_BAO.\n\n");
902
903            return false;
904        }
905    }
906
907    // un problÚme ?
908
909    catch ( SocketException& e )
910    {
911        ErreurLog("Exception was caught:" + e.description() + "\n");
912
913        return false;
914    }
915
916    return true;
917}
918
919
920
921/**************************************************************************************
922** Envoie la méthode d'alignement au pilote indi_bao
923** Ce paramÚtre peut être SIMPLE, AFFINE ou TAKI
924**
925***************************************************************************************/
926
927bool BAOcontrol::EnvoyerMethodeAlignement()
928{
929    stringstream os;
930
931    try
932    {
933        *client_socket << "<newSwitchVector device=\"BAO\" name=\"ALIGNMENT_SET\">";
934        *client_socket << "<oneSwitch name=\"SIMPLE\">";
935        (MethodeAlignement == SIMPLE) ? *client_socket << "On" : *client_socket << "Off";
936        *client_socket << "</oneSwitch>";
937        *client_socket << "<oneSwitch name=\"AFFINE\">";
938        (MethodeAlignement == AFFINE) ? *client_socket << "On" : *client_socket << "Off";
939        *client_socket << "</oneSwitch>";
940        *client_socket << "<oneSwitch name=\"TAKI\">";
941        (MethodeAlignement == TAKI)   ? *client_socket << "On" : *client_socket << "Off";
942        *client_socket << "</oneSwitch>";
943        *client_socket << "</newSwitchVector>";
944
945        if (!VerifReponse("name=\"ALIGNMENT_SET\" state=\"Ok\"", NULL))
946        {
947            ErreurLog("ERREUR fct EnvoyerMethodeAlignement : pas de réponse du pilote indi_BAO.\n\n");
948
949            return false;
950        }
951    }
952
953    // un problÚme ?
954
955    catch ( SocketException& e )
956    {
957        ErreurLog("Exception was caught:" + e.description() + "\n");
958
959        return false;
960    }
961
962    return true;
963}
964
965
966/**************************************************************************************
967** Envoie une commande aux antennes
968** exemples : P, Z, A, Gf1000f0100
969**
970***************************************************************************************/
971
972bool BAOcontrol::EnvoyerCommande(string commande, string *Message)
973{
974    stringstream os;
975
976    if (Message) *Message = "";
977
978    try
979    {
980        *client_socket << "<newTextVector device=\"BAO\" name=\"COMMAND_SET\">";
981        *client_socket << "<oneText name=\"COMMAND\">";
982        *client_socket << commande;
983        *client_socket << "</oneText>";
984        *client_socket << "</newTextVector>";
985
986        if (commande == "X")
987        {
988            if (!VerifReponse("Position:", Message))
989            {
990                ErreurLog("Pas de réponse de l'antenne à la requête X.\n\n");
991
992                return false;
993            }
994
995            return true;
996        }
997
998        if (commande == "D")
999        {
1000            if (!VerifReponse("Deltas:", Message))
1001            {
1002                ErreurLog("Pas de réponse de l'antenne à la requête D.\n\n");
1003
1004                return false;
1005            }
1006
1007            return true;
1008        }
1009
1010        if (commande == "C")
1011        {
1012            if (!VerifReponse("Corrections:", Message))
1013            {
1014                ErreurLog("Pas de réponse de l'antenne à la requête C.\n\n");
1015
1016                return false;
1017            }
1018
1019            return true;
1020        }
1021
1022        if (commande == "M")
1023        {
1024            if (!VerifReponse("Calcul des matrices de correction", Message))
1025            {
1026                ErreurLog("Pas de réponse de l'antenne à la requête M.\n\n");
1027
1028                return false;
1029            }
1030
1031            return true;
1032        }
1033
1034        if (commande == "O")
1035        {
1036            if (!VerifReponse("Optimisation de la geometrie de l antenne", Message))
1037            {
1038                ErreurLog("Pas de réponse de l'antenne à la requête O.\n\n");
1039
1040                return false;
1041            }
1042
1043            return true;
1044        }
1045
1046        if (commande == "R")
1047        {
1048            if (!VerifReponse("Reinitialisation de la matrice de correction", Message))
1049            {
1050                ErreurLog("Pas de réponse de l'antenne à la requête R.\n\n");
1051
1052                return false;
1053            }
1054
1055            return true;
1056        }
1057
1058        if (!VerifReponse("name=\"COMMAND_SET\" state=\"Ok\"", NULL))
1059        {
1060            ErreurLog("ERREUR fct EnvoyerCommande : pas de réponse du pilote indi_BAO.\n\n");
1061
1062            return false;
1063        }
1064    }
1065
1066    // un problÚme ?
1067
1068    catch ( SocketException& e )
1069    {
1070        ErreurLog("Exception was caught:" + e.description() + "\n");
1071
1072        return false;
1073    }
1074
1075    if (Message)
1076    {
1077        if (*Message != "") AfficherLog(*Message +"\n\n", true);
1078    }
1079
1080    return true;
1081}
1082
1083
1084
1085/**************************************************************************************
1086** Place les antennes en position de repos
1087**
1088***************************************************************************************/
1089
1090bool BAOcontrol::Park()
1091{
1092    try
1093    {
1094        *client_socket << "<newSwitchVector device=\"BAO\" name=\"\" >";
1095        *client_socket << "<oneSwitch name=\"PARK\">";
1096        *client_socket << "On";
1097        *client_socket << "</oneSwitch>";
1098        *client_socket << "</newSwitchVector>";
1099
1100        if (!VerifReponse("PARK OK", NULL))
1101        {
1102            ErreurLog("La commande PARK a échoué.\n\n");;
1103
1104            return false;
1105        }
1106    }
1107    catch ( SocketException& e)
1108    {
1109        ErreurLog("Exception was caught:" + e.description() + "\n");
1110
1111        return false;
1112    }
1113
1114    AfficherLog("Le pilote indi_BAO a bien reçu la commande PARK.\n\n", true);
1115
1116    return true;
1117}
1118
1119
1120
1121/**************************************************************************************
1122** Annule le mouvement en cours
1123**
1124***************************************************************************************/
1125
1126bool BAOcontrol::Abort()
1127{
1128    try
1129    {
1130        *client_socket << "<newSwitchVector device=\"BAO\" name=\"ABORT_MOTION\" >";
1131        *client_socket << "<oneSwitch name=\"ABORT\">";
1132        *client_socket << "On";
1133        *client_socket << "</oneSwitch>";
1134        *client_socket << "</newSwitchVector>";
1135
1136        if (!VerifReponse("ABORT OK", NULL))
1137        {
1138            ErreurLog("L'annulation a échoué.\n\n");
1139
1140            return false;
1141        }
1142    }
1143    catch ( SocketException& e)
1144    {
1145        ErreurLog("Exception was caught:" + e.description() + "\n");
1146
1147        return false;
1148    }
1149
1150    AfficherLog("Le pilote indi_BAO a bien reçu la commande ABORT.\n\n", true);
1151
1152    return true;
1153}
1154
1155
1156/**************************************************************************************
1157** Alignement de l'antenne ip
1158**
1159***************************************************************************************/
1160
1161bool BAOcontrol::SelectionIP(string ip)
1162{
1163    try
1164    {
1165        *client_socket << "<newTextVector device=\"BAO\" name=\"ALIGNEMENT_IP\">";
1166        *client_socket << "<oneText name=\"IP\">";
1167        *client_socket << ip;
1168        *client_socket << "</oneText>";
1169        *client_socket << "</newTextVector>";
1170
1171
1172        if (!VerifReponse("est maintenant prete pour l alignement", NULL))
1173        {
1174            ErreurLog("La sélection de l'antenne située à l'adresse ip a échoué.\n\n");
1175
1176            return false;
1177        }
1178    }
1179    catch ( SocketException& e)
1180    {
1181        ErreurLog("Exception was caught:" + e.description() + "\n");
1182
1183        return false;
1184    }
1185
1186    AfficherLog("Le pilote indi_BAO a bien sélectionné l'antenne situé à l'adresse ip pour l'alignement.\n\n", true);
1187
1188    return true;
1189}
1190
1191
1192/**************************************************************************************
1193** Augmenter ou diminuer le delta en ascension droite ou en déclinaison
1194**
1195***************************************************************************************/
1196
1197bool BAOcontrol::AlignementDelta(string delta, bool azimut)
1198{
1199    string Message = "";
1200
1201    try
1202    {
1203        if (azimut)
1204        {
1205            if (delta == "-1")
1206            {   *client_socket << "<newSwitchVector device=\"BAO\" name=\"AZ\" >";
1207                *client_socket << "<oneSwitch name=\"AZM\">";
1208                *client_socket << "On";
1209                *client_socket << "</oneSwitch>";
1210                *client_socket << "</newSwitchVector>";
1211            }
1212            else
1213            {
1214                *client_socket << "<newSwitchVector device=\"BAO\" name=\"AZ\" >";
1215                *client_socket << "<oneSwitch name=\"AZP\">";
1216                *client_socket << "On";
1217                *client_socket << "</oneSwitch>";
1218                *client_socket << "</newSwitchVector>";
1219            }
1220
1221            if (!VerifReponse("Delta", &Message))
1222            {
1223                ErreurLog("BAOcontrol:AlignementDelta a échoué.\n\n");
1224
1225                return false;
1226            }
1227        }
1228        else
1229        {
1230            if (delta == "-1")
1231            {
1232                *client_socket << "<newSwitchVector device=\"BAO\" name=\"ALT_N\" >";
1233                *client_socket << "<oneSwitch name=\"ALTN\">";
1234                *client_socket << "On";
1235                *client_socket << "</oneSwitch>";
1236                *client_socket << "</newSwitchVector>";
1237
1238                if (!VerifReponse("Delta", &Message))
1239                {
1240                    ErreurLog("BAOcontrol:AlignementDelta a échoué.\n\n");
1241
1242                    return false;
1243                }
1244            }
1245            else
1246            {
1247                *client_socket << "<newSwitchVector device=\"BAO\" name=\"ALT_P\" >";
1248                *client_socket << "<oneSwitch name=\"ALTP\">";
1249                *client_socket << "On";
1250                *client_socket << "</oneSwitch>";
1251                *client_socket << "</newSwitchVector>";
1252
1253                if (!VerifReponse("Delta", &Message))
1254                {
1255                    ErreurLog("BAOcontrol:AlignementDelta a échoué.\n\n");
1256
1257                    return false;
1258                }
1259            }
1260        }
1261
1262        if (Message != "") AfficherLog(Message + "\n\n", true);
1263    }
1264    catch ( SocketException& e)
1265    {
1266        ErreurLog("Exception was caught:" + e.description() + "\n");
1267
1268        return false;
1269    }
1270
1271//   AfficherLog("Le pilote indi_BAO a bien sélectionné l'antenne situé à l'adresse ip pour l'alignement.\n\n", true);
1272
1273    return true;
1274}
1275
1276
1277/**************************************************************************************
1278** Validation de l'alignement sur l'étoile visée actuellement
1279**
1280***************************************************************************************/
1281
1282bool BAOcontrol::ValidationAlignement()
1283{
1284    try
1285    {
1286        *client_socket << "<newSwitchVector device=\"BAO\" name=\"ALIGNMENT_OK\" >";
1287        *client_socket << "<oneSwitch name=\"OK\">";
1288        *client_socket << "On";
1289        *client_socket << "</oneSwitch>";
1290        *client_socket << "</newSwitchVector>";
1291
1292        if (!VerifReponse("alignement ont ete valides", NULL))
1293        {
1294            ErreurLog("L'alignement sur l'étoile n'a pu être validé.\n\n");
1295
1296            return false;
1297        }
1298    }
1299    catch ( SocketException& e)
1300    {
1301        ErreurLog("Exception was caught:" + e.description() + "\n");
1302
1303        return false;
1304    }
1305
1306    AfficherLog("L'alignement sur l'étoile a bien été validé.\n\n", true);
1307
1308    return true;
1309}
1310
1311
1312/**************************************************************************************
1313** Sauvegarde de l'alignement
1314**
1315***************************************************************************************/
1316
1317bool BAOcontrol::SauvegardeAlignement()
1318{
1319    try
1320    {
1321        *client_socket << "<newSwitchVector device=\"BAO\" name=\"ALIGNMENT_OK\" >";
1322        *client_socket << "<oneSwitch name=\"SAUV\">";
1323        *client_socket << "On";
1324        *client_socket << "</oneSwitch>";
1325        *client_socket << "</newSwitchVector>";
1326
1327        if (!VerifReponse("Les parametres de l alignement ont ete sauvegardes", NULL))
1328        {
1329            ErreurLog("La sauvegarde des paramÚtres de l'alignement a échoué.\n\n");
1330
1331            return false;
1332        }
1333    }
1334    catch ( SocketException& e)
1335    {
1336        ErreurLog("Exception was caught:" + e.description() + "\n");
1337
1338        return false;
1339    }
1340
1341    AfficherLog("Les paramÚtres de l'alignement ont bien été sauvegardés.\n\n", true);
1342
1343    return true;
1344}
1345
1346
1347
1348/**************************************************************************************
1349** Sauvegarde de l'alignement
1350**
1351***************************************************************************************/
1352
1353bool BAOcontrol::ResetAlignement()
1354{
1355    try
1356    {
1357        *client_socket << "<newSwitchVector device=\"BAO\" name=\"ALIGNMENT_RESET\" >";
1358        *client_socket << "<oneSwitch name=\"RESET\">";
1359        *client_socket << "On";
1360        *client_socket << "</oneSwitch>";
1361        *client_socket << "</newSwitchVector>";
1362
1363        if (!VerifReponse("reinitialises", NULL))
1364        {
1365            ErreurLog("Impossible de réinitialiser les paramÚtres d'alignement de l'antenne.\n\n");
1366
1367            return false;
1368        }
1369    }
1370    catch ( SocketException& e)
1371    {
1372        ErreurLog("Exception was caught:" + e.description() + "\n");
1373
1374        return false;
1375    }
1376
1377    AfficherLog("Les paramÚtres d'alignement de l'antenne ont été réinitialisés.\n\n", true);
1378
1379    return true;
1380}
1381
1382
1383/**************************************************************************************
1384** Sélection vitesse alignement
1385**
1386***************************************************************************************/
1387
1388bool BAOcontrol::VitesseAlignement(int vit)
1389{
1390    string Message = "";
1391
1392    try
1393    {
1394        if (vit == 1)
1395        {
1396            *client_socket << "<newSwitchVector device=\"BAO\" name=\"RAQ\" >";
1397            *client_socket << "<oneSwitch name=\"RAQ1\">";
1398            *client_socket << "On";
1399            *client_socket << "</oneSwitch>";
1400            *client_socket << "</newSwitchVector>";
1401
1402            if (!VerifReponse("La vitesse de la raquette est fixee a 1x", &Message))
1403            {
1404                ErreurLog("Impossible de modifier la vitesse de la raquette.\n\n");
1405
1406                return false;
1407            }
1408        }
1409        else
1410        {
1411            *client_socket << "<newSwitchVector device=\"BAO\" name=\"RAQ\" >";
1412            *client_socket << "<oneSwitch name=\"RAQ10\">";
1413            *client_socket << "On";
1414            *client_socket << "</oneSwitch>";
1415            *client_socket << "</newSwitchVector>";
1416
1417            if (!VerifReponse("La vitesse de la raquette est fixee a 10x", &Message))
1418            {
1419                ErreurLog("Impossible de modifier la vitesse de la raquette.\n\n");
1420
1421                return false;
1422            }
1423        }
1424
1425
1426
1427    }
1428    catch ( SocketException& e)
1429    {
1430        ErreurLog("Exception was caught:" + e.description() + "\n");
1431
1432        return false;
1433    }
1434
1435    if (Message != "") AfficherLog(Message +"\n\n", true);
1436
1437    return true;
1438}
1439
1440/**************************************************************************************
1441** Dirige l'antenne vers les coordonnées ar et dec et suit l'objet  en activant le mode
1442** transit ou tracking.
1443**
1444** si J2000 == true, cela signifie que les coordonnées ar et dec sont données dans le
1445** le systÚme de coordonnées J2000 (écliptique et équinoxe du 1 janvier 2000 à 0 h TU)
1446** Des calculs supplémentaires (précession, nutation, aberration) sont alors réalisés
1447** pour ramener les coordonnées horaires à l'écliptique et l'équinoxe de la date de
1448** l'observation.
1449**
1450***************************************************************************************/
1451
1452bool BAOcontrol::Goto(string ar, string dec, bool Transit, bool J2000)
1453{
1454    double arf, decf;
1455    float  ar1, ar2, ar3;
1456    float  dec1, dec2, dec3;
1457
1458
1459    // Conversion de l'AD et de la déclinaison en radians
1460
1461    Decomposition(ar, 2, &ar1, &ar2, &ar3);
1462
1463    Decomposition(dec, 0, &dec1, &dec2, &dec3);
1464
1465    arf  = ( ar1  + ar2 / 60.0  + ar3 / 3600.0 ) * 15.0 * Pidiv180;
1466
1467    decf = ( fabs(dec1) + dec2 / 60.0 + dec3 / 3600.0 ) * Pidiv180;
1468
1469    if (dec[0] == '-') decf = -decf;
1470
1471    // Calculs supplémentaires pour ramener les coordonnées horaires
1472    // à l'époque de l'observation
1473
1474    if ( J2000 )
1475    {
1476        Precession(&arf, &decf);
1477        NutationEtoile(&arf, &decf);
1478        AberrationAnnuelle(&arf, &decf);
1479    }
1480
1481    // on réécrit l'ar et la dec dans le format d'indi_BAO
1482
1483    ar  = DHMS(arf * N180divPi, true);
1484
1485    dec = DHMS(decf * N180divPi, false);
1486
1487    // on en informe l'utilisateur
1488
1489    AfficherLog("Coordonnées apparentes de l'objet :\n", true);
1490
1491    AfficherLog("AD=" + ar  + "   Dec=" + dec +"\n", true);
1492
1493
1494    // On transmet les coordonnées au pilote BAO
1495
1496    try
1497    {
1498        *client_socket << "<newSwitchVector device=\"BAO\" name=\"ON_COORD_SET\">";
1499        *client_socket << "<oneSwitch name=\"TRANSIT\">";
1500        (Transit) ? *client_socket << "On" : *client_socket << "Off";
1501        *client_socket << "</oneSwitch>";
1502
1503        *client_socket << "<oneSwitch name=\"TRACKING\">";
1504        (Transit) ? *client_socket << "Off" : *client_socket << "On";
1505        *client_socket << "</oneSwitch>";
1506        *client_socket << "</newSwitchVector>";
1507
1508        if (!VerifReponse("name=\"ON_COORD_SET\"", NULL))
1509        {
1510            ErreurLog("Le changement de mode TRANSIT/TRACKING a échoué.\n\n");
1511
1512            return false;
1513        }
1514
1515        *client_socket << "<newNumberVector device=\"BAO\" name=\"EQUATORIAL_EOD_COORD_REQUEST\">";
1516        *client_socket << "<oneNumber name=\"RA\">";
1517        *client_socket << ar;
1518        *client_socket << "</oneNumber>";
1519        *client_socket << "<oneNumber name=\"DEC\">";
1520        *client_socket << dec;
1521        *client_socket << "</oneNumber>";
1522        *client_socket << "</newNumberVector>";
1523
1524        if (!VerifReponse("name=\"EQUATORIAL_EOD_COORD_REQUEST\"", NULL))
1525        {
1526            ErreurLog("Le transfert des coordonnées de l'objet a échoué.\n\n");
1527
1528            return false;
1529        }
1530    }
1531    catch ( SocketException& e)
1532    {
1533        ErreurLog("Exception was caught:" + e.description() + "\n");
1534
1535        return false;
1536    }
1537
1538    AfficherLog("Les nouvelles coordonnées AD=" + ar + " Dec=" + dec, true);
1539    AfficherLog(" ont été envoyées au pilote indi_BAO.\n\n", true);
1540
1541    return true;
1542}
1543
1544
1545
1546/**************************************************************************************
1547** Se connecte ou se déconnecte au pilote indi_BAO
1548**
1549***************************************************************************************/
1550
1551bool BAOcontrol::Connect(bool connect)
1552{
1553    try
1554    {
1555        *client_socket << "<newSwitchVector device=\"BAO\" name=\"CONNECTION\">";
1556
1557        (connect) ? *client_socket << "<oneSwitch name=\"CONNECT\">" : *client_socket << "<oneSwitch name=\"DISCONNECT\">";
1558
1559        *client_socket << "On";
1560        *client_socket << "</oneSwitch>";
1561        *client_socket << "</newSwitchVector>";
1562
1563        if (connect)
1564        {
1565            if (!VerifReponse("BAORadio is online", NULL))
1566            {
1567                ErreurLog("La connexion a échoué.\n\n");
1568
1569                return false;
1570            }
1571        }
1572        else
1573        {
1574            if (!VerifReponse("BAORadio is offline", NULL))
1575            {
1576                ErreurLog("La déconnexion a échoué.\n\n");
1577
1578                return false;
1579            }
1580        }
1581    }
1582
1583    catch ( SocketException& e )
1584    {
1585        ErreurLog("Exception was caught:" + e.description() + "\n");
1586
1587        return false;
1588    }
1589
1590    if (connect)
1591    {
1592        AfficherLog("La connexion a été établie avec le pilote indi_BAO.\n\n", true);
1593
1594        // Au moment de la connexion avec le driver indi_BAO
1595        // On transmet les paramÚtres du lieu de l'observation, le mode de suivi
1596        // ainsi que la méthode d'alignement utilisée
1597
1598        usleep(500000);
1599
1600        EnvoyerCoordGeographiques();
1601
1602        EnvoyerPressionTemperature();
1603
1604        EnvoyerDelaisModesTransitEtTracking();
1605
1606        EnvoyerMethodeAlignement();
1607    }
1608    else
1609    {
1610        AfficherLog("BAOcontrol s'est bien déconnecté du pilote indi_BAO.\n\n", true);
1611    }
1612
1613    return true;
1614}
1615
1616
1617/**************************************************************************************
1618** Gestion du clavier en mode raw pendant la procédure d'alignement
1619** Cela permet de ne pas avoir à taper sur la touche 'entrée' aprÚs avoir appuyé sur
1620** une flÚche de direction
1621**
1622***************************************************************************************/
1623
1624void mode_raw(int activer)
1625{
1626    static struct termios cooked;
1627    static int raw_actif = 0;
1628
1629    if (raw_actif == activer)
1630        return;
1631
1632    if (activer)
1633    {
1634        struct termios raw;
1635
1636        tcgetattr(STDIN_FILENO, &cooked);
1637
1638        raw = cooked;
1639        cfmakeraw(&raw);
1640        tcsetattr(STDIN_FILENO, TCSANOW, &raw);
1641    }
1642    else
1643        tcsetattr(STDIN_FILENO, TCSANOW, &cooked);
1644
1645    raw_actif = activer;
1646}
1647
1648
1649/**************************************************************************************
1650** Alignement de l'antenne située à l'adresse ip
1651**
1652** Le principe consiste à utiliser des étoiles comme point de repÚre pour la calibration
1653** des antennes : on compare la position calculée de chaque objet avec la position
1654** effectivement mesurée lors de la procédure d'alignement. On en tire  une matrice
1655** de rotation qui doit corriger les défauts d'alignement de l'antenne (le 0 pas codeur
1656** pas  parfaitement dirigé vers le sud et un axe de rotation az pas forcément
1657** perpendiculaire au sol...)
1658**
1659***************************************************************************************/
1660
1661bool BAOcontrol::AlignementAntenneIP( string ip )
1662{
1663
1664    stringstream os;
1665
1666    int i;
1667
1668    ModificationAlignement=false;
1669
1670
1671    // on a identifié l'antenne
1672
1673    if ( SelectionIP(ip) )
1674    {
1675        // L'alignement de l'antenne 'num' est en cours. Il ne faut pas calculer la
1676        // matrice de correction tant que ce n'est pas fini...
1677
1678        AfficherLog("Début de l'alignement de l'antenne.\n", true);
1679
1680        AfficherLog("\n\n\nListe des étoiles brillantes situées à plus de 30° au-dessus de l'horizon :\n\n", true);
1681
1682        // Mise à jour  du temps sidéral local
1683
1684        UpdateTime();
1685
1686        // recherche les étoiles situées à une hauteur supérieure à 30 °
1687        // (et donc accessibles à l'antenne)
1688
1689        for (i=0; i<numEtoiles; i++)
1690        {
1691            Azimut(Etoiles[i].ad, Etoiles[i].de, &Etoiles[i].az, &Etoiles[i].ha);
1692
1693            // calcule la réfraction atmosphérique
1694
1695            Etoiles[i].ha = RefractionAtmospherique(Etoiles[i].ha);
1696
1697            // Sélectionne et affiche les étoiles > 30°
1698            // et donc la magnitude < MAGNITUDEMAXETOILESCALIBRATION
1699
1700            Etoiles[i].selectionnee = ((Etoiles[i].ha > (HAUTMIN + 5.0 ) * Pidiv180) && (Etoiles[i].mag < MAGNITUDEMAXETOILESCALIBRATION));
1701
1702            if ( Etoiles[i].selectionnee )
1703            {
1704                os.width(20);
1705                os << Etoiles[i].nom;
1706                os << "\t(" << Etoiles[i].cons << ")\taz=" << Etoiles[i].az * N180divPi << "°\tha=";
1707                os << Etoiles[i].ha * N180divPi << "°\tmagnitude=" << Etoiles[i].mag << "\n";
1708
1709                AfficherLog(&os, true);
1710            }
1711
1712            //TODO à réactiver
1713            /* if (Etoiles[i].selectionnee)
1714             {
1715                 for (int j=0; j < Antennes[num].AlignementAntenne->nbrcorrections; j++)
1716                 {
1717                     // Là, un point important: on ne prend pas en compte l'AD des objets dans le reste des calculs
1718                     // Mais l'angle horaire de ces objets avec le méridien. Voir les détails dans la documentation....
1719
1720                     double distances = DistanceAngulaireEntre2Points(
1721                                            VerifAngle(Antennes[num].AlignementAntenne->ad[j] - Antennes[num].AlignementAntenne->tsl[j]),
1722                                            Antennes[num].AlignementAntenne->de[j],
1723                                            VerifAngle(Etoiles[i].ad - GetTSL()),
1724                                            Etoiles[i].de);
1725
1726                     // Ici, on ne sélectionne que des étoiles qui ne sont pas trop proches de positions ayant déjà servies à la calibration
1727                     // de l'antenne et qui multiplierait les mesures sans amélioration de la précision
1728
1729                     if ( distances < MIN_DISTANCE_ALIGNEMENT ) Etoiles[i].selectionnee = false;
1730                 }
1731             }*/
1732        }
1733    }
1734    else
1735    {
1736        ErreurLog("L'antenne située à l'adresse ip indiquée n'existe pas\n\n");
1737
1738        return false;
1739    }
1740
1741    return true;
1742}
1743
1744
1745
1746
1747
1748/**************************************************************************************
1749** Lance l'exécution d'un fichier de mouvements
1750**
1751***************************************************************************************/
1752
1753bool BAOcontrol::Run(string fichier)
1754{
1755    stringstream os;
1756
1757    bool exec = LectureFichierMouvements(fichier);
1758
1759    UpdateTime();
1760
1761    if ( exec && numobjets > 1 )
1762    {
1763        // Si le chargement du fichier s'est bien déroulé et qu'il y a plus d'un mouvement dedans
1764
1765        if (objets[numobjets-1].JJ + objets[numobjets-1].Duree / 3600.0 / 24.0 < GetJJ())
1766        {
1767            ErreurLog("Le fichier contient des dates qui sont toutes périmées. Exécution annulée.\n\n");
1768
1769            NoExit = !exitrun;
1770
1771            return false;
1772        }
1773        else
1774        {
1775            AfficherLog("Exécution du fichier " + fichier + " en attente...\n\n", true);
1776            run = true;
1777        }
1778    }
1779    else
1780    {
1781        ErreurLog("\nLe fichier " + fichier + " contient des erreurs ou n'existe pas...\n\n\n");
1782
1783        NoExit=!exitrun;
1784
1785        return false;
1786    }
1787
1788    return true;
1789}
1790
1791
1792
1793
1794/**************************************************************************************
1795** identification des commandes entrées par l'utilisateur
1796** puis exécution des commandes
1797** Chaine peut contenir par ex "goto betelgeuse", "goto 12:23:01 +22:53:00", "status" etc...
1798**
1799***************************************************************************************/
1800
1801string BAOcontrol::DecodageEntreesUtilisateur(string chaine)
1802{
1803    string ar, de, objet, fichier;
1804    stringstream os;
1805
1806    // Permet de savoir si la derniÚre commande saisie par l'utilisateur
1807    // est une commande valide
1808
1809    bool CommandeOK = false;
1810
1811
1812    // Commande goto
1813
1814    if ( chaine.find("goto") != string::npos )
1815    {
1816
1817        // L'utilisateur a fait suivre la commande goto de l'indication J2000
1818
1819        J2000 = (chaine.find("j2000") != string::npos);
1820
1821        if ( J2000 )
1822        {
1823            AfficherLog("Prise en compte de la précession, de la nutation et de l'aberration...\n", true);
1824
1825            // On ne garde que la premiÚre partie de la chaine (avant le mot "J2000")
1826
1827            chaine = chaine.substr(0, chaine.find("J2000"));
1828        }
1829
1830        if (DecompositionCommande(chaine, "goto", &ar, &de) &&
1831                Decomposition(ar, 2, NULL, NULL, NULL) &&
1832                Decomposition(de, 0, NULL, NULL, NULL))
1833        {
1834            // L'utilisateur a indiqué deux coordonnées valides -> on exécute le goto
1835
1836            CommandeOK = true;
1837
1838            Goto(ar, de, Transit, J2000);
1839        }
1840        else
1841        {
1842            // L'utilisateur a indiqué un nom d'objet aprÚs le goto -> on lance la recherche sur internet
1843            // puis on envoie les coordonnées de l'objet au pilote indi_BAO
1844
1845            CommandeOK = true;
1846
1847            if ((DecompositionCommande(chaine, "goto", &objet, NULL)) && (chaine.find(":") == string::npos))
1848            {
1849                CoordonneesHoraires reponse;
1850
1851                if (objet != "sun")
1852                {
1853                    bool CestUneEtoile = false;
1854
1855                    for (int i=0; i<numEtoiles; i++)
1856                    {
1857                        if (objet == Etoiles[i].nom)
1858                        {
1859                            AfficherLog(Etoiles[i].nom + "\n", true);
1860
1861                            Goto( DHMS(Etoiles[i].ad*N180divPi, true), DHMS(Etoiles[i].de*N180divPi, false), Transit, true);
1862
1863                            CestUneEtoile = true;
1864
1865                            break;
1866                        }
1867                    }
1868
1869                    if (!CestUneEtoile)
1870                    {
1871                        reponse = ServeurNED(objet);
1872
1873                        if (reponse.ar!="" && reponse.dec!="")  Goto(reponse.ar, reponse.dec, Transit, true);
1874                    }
1875                }
1876                else
1877                {
1878                    CoordonneesHorairesDouble pos_sun;
1879
1880                    CalculARDecSoleil(&pos_sun);
1881
1882                    printf("Goto Sun\n");
1883
1884                    Goto(DHMS(pos_sun.ar * N180divPi, true), DHMS(pos_sun.dec * N180divPi, false), Transit, false);
1885                }
1886            }
1887            else
1888            {
1889                ErreurLog("Erreur goto : le format de la commande est goto AD DEC\n \
1890                 L'AD doit être de la forme xx:yy:zz  J2000 (ex: 12:00:03 pour 12h 0m 3s)\n \
1891                 La déclinaison doit être de la forme +/-xx:yy:zz (ex: -12:50:01.1 pour -12° 50' 01.1'')\n \
1892                 J2000 est un paramÚtre optionnel qui sert à indiquer que les coordonnées horaires\n \
1893                 sont exprimées dans le repÚre du même nom.\n\n \
1894                 Il est egalement possible de faire suivre la commande d'un nom d'un objet\n \
1895                 Exemple goto M 31 ou encore goto ngc145.\n \
1896                 Ne pas préciser dans ce cas J2000.\n\n");
1897            }
1898        }
1899    }
1900
1901
1902
1903    // Commande goto
1904
1905    if ( chaine.find("raq") != string::npos )
1906    {
1907        int Vitesse = 10;
1908        // L'utilisateur a indiqué un nom d'objet aprÚs le goto -> on lance la recherche sur internet
1909        // puis on envoie les coordonnées de l'objet au pilote indi_BAO
1910
1911        CommandeOK = true;
1912
1913        char c;
1914
1915        do
1916        {
1917
1918            cout << "Appuyez sur les touches Z,Q,D,X pour déplacer l'objet dans le viseur.\n";
1919            cout << "Appuyez sur S pour changer de vitesse et sur A pour envoyer un ABORT à l'antenne.\n";
1920            cout << "(A la fin de l'opération, appuyez sur ESC pour sortir de la raquette).\n\n";
1921
1922            mode_raw(1);
1923
1924            c = getchar();
1925
1926            mode_raw(0);
1927
1928            // pause de 10ms
1929
1930            usleep(10000);
1931
1932            // Gestion des touches du clavier. On modifie l'orientation de l'instrument
1933            // sur les axes AD et Dec...
1934            // On sauvegarde également le temps sidéral local. Ceci nous permettra de calculer
1935            // l'angle horaire de l'objet pointé
1936
1937
1938            switch (c)
1939            {
1940            case 'z' :
1941                AlignementDelta("1", false);
1942                break;
1943
1944            case 'd' :
1945                AlignementDelta("1", true);
1946                break;
1947
1948            case 'q' :
1949                AlignementDelta("-1", true);
1950                break;
1951
1952            case 'x' :
1953                AlignementDelta("-1", false);
1954                break;
1955
1956                // abort
1957            case 'a' :
1958                Abort();
1959                sleep(2);
1960
1961                break;
1962
1963                // vitesse 1x ou 10x
1964            case 's' :
1965                (Vitesse == 1 ) ? Vitesse = 10 : Vitesse = 1;
1966                VitesseAlignement(Vitesse);
1967                os << "Vitesse=" << Vitesse << "x\n\n";
1968                AfficherLog(&os,  true);
1969
1970                break;
1971            }
1972            //touche ESC -> on sort
1973        } while (c!=27);
1974    }
1975
1976
1977
1978
1979
1980
1981// Annulation du suivi en cours
1982
1983    if (chaine.find("abort") != string::npos)
1984    {
1985        CommandeOK = true;
1986
1987        Abort();
1988
1989        // Annulation de l'exécution d'un fichier de mouvements
1990
1991        if (chaine.find("run") != string::npos)
1992        {
1993            run       = false;
1994            runnum    = 1;
1995            numobjets = 1;
1996
1997            AfficherLog("Annulation de l'exécution du fichier de mouvements.\n\n", true);
1998
1999            return "";
2000        }
2001    }
2002
2003// Lance l'exécution d'un fichier de mouvements
2004
2005    if (chaine.find("run") != string::npos)
2006    {
2007        CommandeOK = true;
2008
2009        if (DecompositionCommande(chaine, "run", &fichier, NULL))
2010        {
2011            Run(fichier);
2012        }
2013        else
2014        {
2015            ErreurLog("Erreur run : la commande run doit être suivie par un nom de fichier.\n\n");
2016        }
2017    }
2018
2019// se connecte/déconnecte au serveur
2020
2021    if (chaine.find("connect") != string::npos)
2022    {
2023        CommandeOK = true;
2024
2025        Connect(chaine.find("disconnect") == string::npos);
2026    }
2027
2028
2029
2030// Place les antennes en position de repos
2031
2032    if (chaine.find("park") != string::npos)
2033    {
2034        CommandeOK = true;
2035
2036        Park();
2037    }
2038
2039// interroge un serveur de temps pour mettre l'horloge du PC à jour
2040
2041    if (chaine.find("updatetime") != string::npos)
2042    {
2043        CommandeOK = true;
2044
2045        int rc = system("sntp -s fr.pool.ntp.org");
2046
2047        if (WEXITSTATUS(rc) ==-1 || WEXITSTATUS(rc) ==127)
2048        {
2049            ErreurLog("La commande sntp n'est pas accessible. Merci de vérifier.\n\n");
2050        }
2051    }
2052
2053// Affiche tous les paramÚtres du programme
2054
2055    if (chaine.find("status") != string::npos)
2056    {
2057        CommandeOK = true;
2058
2059        os << "Latitude = " << LatitudeChar << "\n";
2060        os << "Longitude = " << LongitudeChar << "\n\n";
2061        os << "Serveur Indi = " << Serveur << "\n";
2062        os << "Port du serveur Indi = " << Port << "\n\n";
2063        os << "Pression atmosphérique  = " << Pression << " mBar\n";
2064        os << "Température = " << Temperature << " °C\n\n";
2065
2066        os << "Antennes connectées : " << numAntennes << "\n\n";
2067        os << "Mode ";
2068        (Transit) ? os << "transit" : os << "tracking";
2069        os << " activé.\n\n";
2070        os << "Durée entre deux actualisations : ";
2071        (Transit) ? os << delaitransit : os << delaitracking;
2072        os << " sec(s)\n\n";
2073        os << "Méthode d'alignement : ";
2074        switch (MethodeAlignement)
2075        {
2076        case SIMPLE :
2077            os << "simple\n";
2078            break;
2079        case AFFINE :
2080            os << "affine\n";
2081            break;
2082        case TAKI   :
2083            os << "taki\n";
2084            break;
2085        }
2086        os << "\n\n";
2087
2088        AfficherLog(&os, true);
2089    }
2090
2091// interroge le serveur NED sur internet -> retourne les coordonnées de l'objet
2092
2093    if (chaine.find("search")!=string::npos)
2094    {
2095        string objet;
2096
2097        bool CestUneEtoile = false;
2098
2099        CommandeOK = true;
2100
2101        if (DecompositionCommande(chaine, "search", &objet, NULL))
2102        {
2103            for (int i=0; i<numEtoiles; i++)
2104            {
2105                if (objet == Etoiles[i].nom)
2106                {
2107                    os << Etoiles[i].nom << "\n";
2108                    os << "AD (J2000) = " << DHMS(Etoiles[i].ad*N180divPi, true) << "\n";
2109                    os << "Dec (J2000) = " << DHMS(Etoiles[i].de*N180divPi, false) << "\n";
2110                    AfficherLog(os.str(), true);
2111
2112                    CestUneEtoile = true;
2113
2114                    break;
2115                }
2116            }
2117
2118            if (!CestUneEtoile) ServeurNED(objet);
2119        }
2120    }
2121
2122
2123// Envoyer une commande aux antennes
2124
2125    if (chaine.find("send")!=string::npos)
2126    {
2127        string commande;
2128
2129        CommandeOK = true;
2130
2131        if (DecompositionCommande(chaine, "send", &commande, NULL))
2132        {
2133            switch (commande[0])
2134            {
2135            case 'g' :
2136                commande[0]='G';
2137                if ((commande[1]!='f' && commande[1]!='b') || (commande[6]!='f' && commande[6]!='b'))
2138                {
2139                    ErreurLog("Erreur ! La commande GOTO n'a pas un format correct !\n\n");
2140                    return "";
2141                }
2142                break;
2143            case 'a' :
2144                commande[0]='A';
2145                break;
2146            case 'z' :
2147                commande[0]='Z';
2148                break;
2149            case 'p' :
2150                commande[0]='P';
2151                break;
2152            case 'x' :
2153                commande[0]='X';
2154                break;
2155            case 'd' :
2156                commande[0]='D';
2157                break;
2158            case 'm' :
2159                commande[0]='M';
2160                break;
2161            case 'o' :
2162                commande[0]='O';
2163                break;
2164            case 'r' :
2165                commande[0]='R';
2166                break;
2167            }
2168
2169
2170
2171            string Message;
2172
2173            if (!EnvoyerCommande((string)commande, &Message))
2174            {
2175                ErreurLog("Erreur ! La commande ne semble pas avoir été executée par l'antenne ou n'a pas un format correct !\n\n");
2176            }
2177            else
2178            {
2179                AfficherLog(Message +"\n\n", true);
2180
2181                return Message;
2182            }
2183        }
2184    }
2185
2186
2187
2188// correction de l'alignement d'une antenne par rapport à l'objet visé
2189
2190    if (chaine.find("align")!=string::npos)
2191    {
2192        string ip;
2193
2194        CommandeOK = true;
2195
2196        if (DecompositionCommande(chaine, "align", &ip, NULL))
2197        {
2198            AlignementAntenneIP(ip);
2199        }
2200        else
2201        {
2202            ErreurLog("Erreur align : la commande align doit être suivie par l'ip de l'antenne qui faut aligner.\n\n");
2203        }
2204    }
2205
2206
2207// Réinitialisation de l'alignement d'une antenne
2208
2209    if (chaine.find("reset")!=string::npos)
2210    {
2211        string ip;
2212
2213        CommandeOK = true;
2214
2215        if (DecompositionCommande(chaine, "reset", &ip, NULL))
2216        {
2217            if (SelectionIP(ip))
2218            {
2219                ResetAlignement();
2220                return "";
2221            }
2222
2223            ErreurLog("Erreur reset : la commande reset doit être suivie par l'ip de l'antenne qu'il faut aligner.\n\n");
2224        }
2225    }
2226
2227
2228// Commande set
2229
2230    if (chaine.find("set") != string::npos)
2231    {
2232        string commande, commande2, commande3;
2233
2234        // est-ce que la commande commande par set ! -> si oui, la variable commande contient alors le reste de
2235        // la phrase saisie par l'utilisateur
2236
2237        if (DecompositionCommande(chaine, "set", &commande, NULL))
2238        {
2239            // A-t-on set transit xxxx ?
2240
2241            if (DecompositionCommande(commande, "transit", &commande2, &commande3))
2242            {
2243                //at-ton set transit delay xxx ?
2244
2245                if (commande2 == "delay")
2246                {
2247                    if (atoi(commande3.c_str()) > 0)
2248                    {
2249                        CommandeOK = true;
2250
2251                        delaitransit = atoi(commande3.c_str());
2252
2253                        EnvoyerDelaisModesTransitEtTracking();
2254
2255                        AfficherLog("Delai entre deux actualisations en mode transit : " + commande3 + "\n\n" , true);
2256                    }
2257                    else
2258                    {
2259                        AfficherLog("Le nombre qui suit le mot clé delay doit être entier et > 0  \n\n" , true);
2260                    }
2261                }
2262
2263                // Active le mode de suivi "transit"
2264
2265                if (commande2 == "on")
2266                {
2267                    CommandeOK = true;
2268
2269                    AfficherLog("Mode transit activé.\n\n", true);
2270
2271                    Transit = true;
2272                }
2273            }
2274
2275            // a-t-on set tracking xxxx ?
2276
2277            if (DecompositionCommande(commande, "tracking", &commande2,  &commande3))
2278            {
2279                // a-ton set tracking delay xxx ?
2280
2281                if (commande2 == "delay")
2282                {
2283                    if (atoi(commande3.c_str())>0)
2284                    {
2285                        CommandeOK = true;
2286
2287                        delaitracking = atoi(commande3.c_str());
2288
2289                        EnvoyerDelaisModesTransitEtTracking();
2290
2291                        AfficherLog("Delai entre deux actualisations en mode tracking : " + commande3 + "\n\n" , true);
2292                    }
2293                    else
2294                    {
2295                        AfficherLog("Le nombre qui suit le mot clé delay doit être entier et > 0  \n\n" , true);
2296                    }
2297                }
2298
2299                // Active le mode de suivi "transit"
2300
2301                if (commande2 == "on")
2302                {
2303                    CommandeOK = true;
2304
2305                    AfficherLog("Mode tracking activé.\n\n", true);
2306
2307                    Transit = false;
2308                }
2309            }
2310
2311            // A-t-on set alignment ?
2312
2313            if (DecompositionCommande(commande, "alignment", &commande2,  &commande3))
2314            {
2315
2316                // A-ton set alignment method xxx ?
2317
2318                if (commande2 == "method")
2319                {
2320                    MethodeAlignement = NONE;
2321
2322                    if (commande3 == "simple") MethodeAlignement = SIMPLE;
2323
2324                    if (commande3 == "affine") MethodeAlignement = AFFINE;
2325
2326                    if (commande3 == "taki")   MethodeAlignement = TAKI;
2327
2328                    if (MethodeAlignement == NONE )
2329                    {
2330                        MethodeAlignement = SIMPLE;
2331
2332                        AfficherLog("Erreur: la syntaxe doit être 'set alignment method x' avec x = simple/affine/taki)\n\n" , true);
2333                    }
2334                    else
2335                    {
2336                        CommandeOK = true;
2337
2338                        EnvoyerMethodeAlignement();
2339
2340                        switch (MethodeAlignement)
2341                        {
2342                        case  SIMPLE :
2343                            AfficherLog("Activation de la méthode d'alignement simple\n\n", true);
2344                            break;
2345                        case  AFFINE :
2346                            AfficherLog("Activation de la méthode d'alignement affine\n\n", true);
2347                            break;
2348                        case  TAKI :
2349                            AfficherLog("Activation de la méthode d'alignement taki\n\n", true);
2350                            break;
2351                        }
2352                    }
2353                }
2354                else
2355                {
2356                    AfficherLog("Erreur: la syntaxe doit être 'set alignment method x' avec x = simple/affine/taki)\n\n" , true);
2357                }
2358            }
2359        }
2360    }
2361
2362
2363
2364
2365
2366
2367// Aide du programme
2368
2369    if (chaine.find("help") != string::npos)
2370    {
2371        CommandeOK = true;
2372
2373        cout << endl;
2374
2375        cout << "connect :                Se connecte au pilote indi_BAO." << endl;
2376        cout << "disconnect :             Se déconnecte du pilote indi_BAO." << endl;
2377        cout << "goto AD Dec :            Pointe l'objet situé aux coordonnées apparentes AD Dec." << endl;
2378        cout << "                         AD doit être au format xx:yy:zz et dec au format +/-xx:yy:zz" << endl;
2379        cout << "                         exemple goto 12:10:05 -05:10:11 permettra de pointer l'objet" << endl;
2380        cout << "                         situé aux coordonnées AD=12h10m5s et dec=-5°10'11''" << endl;
2381        cout << "goto AD Dec J2000 :      Pointe l'objet situé aux coordonnées AD Dec dans le repÚre J2000." << endl;
2382        cout << "                         Avant de pointer l'objet, le programme calcule la précession, la nutation et l'aberration" << endl;
2383        cout << "                         pour ramener les coordonnées à l'écliptique et à l'équinoxe de l'observation." << endl;
2384        cout << "goto nom_objet :         Interroge la base NED pour trouver les coordonnées de l'objet puis le pointe." << endl;
2385        cout << "                         exemples: goto m 31, goto messier 1, goto ngc 175, goto ic 434 etc..." << endl;
2386        cout << "                         Dans ce mode, les coordonnées sont automatiquement rapportées" << endl;
2387        cout << "                         Ã  l'écliptique et à l'équinoxe de l'observation." << endl;
2388        cout << "                         Aussi, merci de ne pas faire suivre les coordonnées de l'indication J2000."<< endl;
2389        cout << "                         Goto sun permet de suivre le soleil." << endl;
2390        cout << "search nom_objet :       Interroge le serveur NED sur internet et retourne les coordonnées de l'objet." << endl;
2391        cout << "align ip :               Lance la procédure d'alignement de l'antenne d'adresse ip." << endl;
2392        cout << "reset ip :               Réinitialise les paramÚtres d'alignement de l'antenne d'adresse ip." << endl;
2393        cout << "send comm :              Envoie la commande 'comm' aux antennes." << endl;
2394        cout << "                         exemples : send P, send A, send Gf1000f1000" << endl;
2395        cout << "set transit on :         Active le mode de suivi transit." << endl;
2396        cout << "set transit delay x :    Fixe la durée entre deux actualisations à x seconde(s) dans le mode transit" << endl;
2397        cout << "set tracking on :        Active le mode de suivi tracking." << endl;
2398        cout << "set tracking delay x :   Fixe la durée entre deux actualisations à x seconde(s) dans le mode tracking" << endl;
2399        cout << "set alignment method x : Aligne les antennes en utilisant la méthode x (simple/affine/taki)" << endl;
2400        cout << "status :                 Liste les paramÚtres du programme." << endl;
2401        cout << "run filename :           Exécute le fichier de mouvements filename." << endl;
2402        cout << "abort run :              Annule l'exécution du fichier de mouvements." << endl;
2403        cout << "abort :                  Annule le mouvement en cours." << endl;
2404        cout << "park :                   Place les antennes en position de repos." << endl;
2405        cout << "updatetime :             Synchronise l'horloge du PC avec un serveur de temps." << endl;
2406        cout << "exit :                   Sortir de BAOControl." << endl;
2407
2408        cout << endl;
2409    }
2410
2411// Bye !
2412
2413    if (chaine.find("exit") != string::npos)
2414    {
2415        CommandeOK = true;
2416
2417        if ( numAntennes > 0 ) Abort();
2418
2419        usleep(500000);
2420
2421        Connect(false);
2422
2423        NoExit = false;
2424
2425        //  pthread_join(th1 ,NULL);
2426    }
2427
2428// La commande n'a pas été identifiée !
2429
2430    if (!CommandeOK) ErreurLog("Commande inconnue... Tapez help pour obtenir la liste des commandes disponibles.\n\n");
2431
2432    return "";
2433}
2434
2435
2436
2437/**************************************************************************************
2438** Interroge le serveur NED sur internet et retourne les coordonnées dans le repÚre J2000
2439** Si pas de réponse, alors message d'erreur et les coordonnées retournées sont
2440** égales à AD="" dec=""
2441**
2442***************************************************************************************/
2443
2444CoordonneesHoraires BAOcontrol::ServeurNED(string objet)
2445{
2446    CoordonneesHoraires reponse;
2447    stringstream send;
2448
2449    FILE *pFile = NULL;
2450    int rc;
2451
2452    //initialisation des variables de retour
2453
2454    reponse.ar = "";
2455    reponse.dec = "";
2456
2457    // le nom de l'objet ne doit pas contenir des espace pour la requête NED
2458    // on les remplace par des '+'
2459
2460    for (uint i=0; i<objet.length(); i++) if (objet[i] == ' ') objet[i]='+';
2461
2462    // Effacer le fichier result s'il existe dans le répertoire du programme
2463
2464    if ((pFile = fopen ("result_recherche_bao", "r")) != NULL )
2465    {
2466        fclose (pFile);
2467        rc = system( "rm -rf result_recherche_bao");
2468    }
2469
2470    // On utilise l'utilitaire curl pour passer la requête au serveur NED
2471    // On sauvegarde le résultat dans le fichier result
2472
2473    send << "curl >> result_recherche_bao \"http://ned.ipac.caltech.edu/cgi-bin/nph-objsearch?objname=";
2474    send << objet;
2475    send << "&extend=no&hconst=73&omegam=0.27&omegav=0.73&corr_z=1&out_csys=Equatorial&out_equinox=J2000.0";
2476    send << "&obj_sort=RA+or+Longitude&of=ascii_bar&zv_breaker=30000.0&list_limit=5&img_stamp=NO\"";
2477
2478    AfficherLog("Envoi de la requête au serveur NED...\n", true);
2479
2480    // on lance la requête
2481
2482    rc = system(send.str().c_str() );
2483
2484    // traitement du résultat
2485
2486    if (WEXITSTATUS(rc) ==-1 || WEXITSTATUS(rc) ==127)
2487    {
2488        ErreurLog("La commande curl n'est pas accessible. Merci de vérifier.\n\n");
2489    }
2490    else
2491    {
2492        // On a reçu quelque chose
2493
2494        int nbRead = 0;
2495
2496        char *pBuf;
2497
2498        pBuf = new char [100000];
2499
2500        // On laisse un peu de temps au serveur pour répondre.
2501        // C'est pas vraiment indispensable mais bon...
2502
2503        sleep(1);
2504
2505        // On ouvre le fichier result
2506
2507        pFile = fopen ("result_recherche_bao", "r");
2508
2509        if (pFile)
2510        {
2511            nbRead = readline (pFile, pBuf);
2512
2513            // Si le fichier n'est pas vide
2514            if (nbRead!=-1)
2515            {
2516                if (strstr(pBuf, "Error") != NULL)
2517                {
2518                    // Le fichier contient une indication d'erreur -> pas de réponse exploitable
2519
2520                    AfficherLog("\nLe serveur NED n'a pas trouvé de réponse à votre demande...\n", true);
2521                }
2522                else
2523                {
2524                    // on analyse la réponse
2525
2526                    AfficherLog("\nRéponse du serveur :\n", true);
2527
2528                    do
2529                    {
2530                        // on cherche la premiÚre suggestion de NED
2531                        // Il faudra peut-être un peu complexifier par la suite
2532
2533                        if (pBuf[0] == '1')
2534                        {
2535                            string chaine = (string)pBuf;
2536
2537                            chaine=chaine.substr(chaine.find('|')+1);
2538
2539                            // affiche le nom de l'objet dans le serveur NED
2540
2541                            AfficherLog(chaine.substr(0, chaine.find('|')) + "\n", true);
2542
2543                            chaine = chaine.substr(chaine.find('|') + 1);
2544
2545                            string chaine2 = chaine.substr(0, chaine.find('|'));
2546
2547                            double ar = atof(chaine2.c_str());
2548
2549                            // affiche l'ascension droite
2550
2551                            AfficherLog("AD (J2000) = " + DHMS(ar, true) + "\n", true);
2552
2553                            reponse.ar = DHMS(ar, true);
2554
2555                            chaine=chaine.substr(chaine.find('|')+1);
2556
2557                            chaine2 = chaine.substr(0, chaine.find('|'));
2558
2559                            double dec = atof(chaine2.c_str());
2560
2561                            // on affiche la déclinaison
2562
2563                            AfficherLog("Dec (J2000) = " + DHMS(dec, false)+"\n", true);
2564
2565                            reponse.dec = DHMS(dec, false);
2566                        }
2567
2568                        nbRead = readline (pFile, pBuf);
2569
2570                    } while (nbRead!=-1);
2571                }
2572            }
2573            else
2574            {
2575                ErreurLog("\nLa connexion semble impossible avec le serveur NED !\n\n");
2576            }
2577
2578            fclose(pFile);
2579        }
2580        else
2581        {
2582            ErreurLog("\nLa connexion semble impossible avec le serveur NED !\n\n");
2583        }
2584
2585        delete [] pBuf;
2586
2587        AfficherLog("\n", true);
2588    }
2589
2590    return reponse;
2591}
2592
2593
2594
2595/**************************************************************************************
2596** Lecture d'un fichier ligne aprÚs ligne
2597** retourne -1 à la fin
2598**
2599***************************************************************************************/
2600
2601int BAOcontrol::readline (FILE * pfile, char *tab)
2602{
2603    int nbchar = 0;
2604
2605    char c;
2606
2607    while ((c = getc (pfile)) != '\n')
2608    {
2609        if (c == EOF)
2610        {
2611            break;
2612        }
2613        tab[nbchar++] = c;
2614    }
2615    tab[nbchar] = '\0';
2616
2617    while (nbchar>0 && tab[nbchar-1]==' ')
2618    {
2619        tab[--nbchar] = '\0';
2620    }
2621
2622    while (tab[0]==' ') for (int i=1; i<=nbchar; i++) tab[i-1] = tab[i];
2623
2624    if (c == EOF) nbchar=-1;
2625
2626    return (nbchar);
2627}
2628
2629
2630
2631/**************************************************************************************
2632** chargement des paramÚtres contenus dans le fichier params
2633**
2634***************************************************************************************/
2635
2636bool BAOcontrol::ChargementParametres(string fileName)
2637{
2638    string section;
2639    string key;
2640    char * value;
2641    stringstream os;
2642
2643
2644    // Si le fichier n'existe pas -> on sort
2645
2646    if (!is_readable(fileName)) return false;
2647
2648
2649    AfficherLog("Lecture du fichier de configuration 'params' :\n\n", true);
2650
2651
2652    /////////////////////////////////////////
2653    // Rubrique Coordonnées géographiques
2654
2655    section = "coordonnees geographiques";
2656
2657    key = "latitude";
2658
2659    if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
2660            && (Decomposition(value, 0, NULL, NULL, NULL)))
2661    {
2662        LatitudeChar = (string)value;
2663        SAFEDELETE_TAB(value);
2664        AfficherLog("latitude = " + LatitudeChar +"\n", true);
2665    }
2666    else
2667    {
2668        ErreurLog("La latitude est incorrecte !\n");
2669
2670        return false;
2671    }
2672
2673
2674    key = "longitude";
2675
2676    if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
2677            && (Decomposition(value, 1, NULL, NULL, NULL)))
2678    {
2679        LongitudeChar = (string)value;
2680        SAFEDELETE_TAB(value);
2681        AfficherLog("longitude = " + LongitudeChar +"\n\n", true);
2682    }
2683    else
2684    {
2685        ErreurLog("La longitude est incorrecte !\n");
2686
2687        return false;
2688    }
2689
2690
2691    /////////////////////////////////////////
2692    // rubrique connexion
2693
2694    section = "connexion indi";
2695
2696    key = "serveur";
2697
2698    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
2699    {
2700        Serveur = (string)value;
2701        SAFEDELETE_TAB(value);
2702        AfficherLog("serveur = " + Serveur +"\n", true);
2703    }
2704    else
2705    {
2706        ErreurLog("Nom du serveur invalide !\n");
2707
2708        return false;
2709    }
2710
2711    /////////////////////////////////////////
2712    // Port de connexion du serveur Indi
2713
2714    key = "port";
2715
2716    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
2717    {
2718        Port = (string)value;
2719        SAFEDELETE_TAB(value);
2720        AfficherLog("port = " + Port +"\n\n", true);
2721    }
2722    else
2723    {
2724        ErreurLog("Numéro de port incorrect !\n");
2725
2726        return false;
2727    }
2728
2729
2730    /////////////////////////////////////////
2731    // Rubrique paramÚtres de l'atmosphÚre
2732
2733    section = "atmosphere";
2734
2735    key = "pression";
2736
2737    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
2738    {
2739        Pression = atof(value);
2740        SAFEDELETE_TAB(value);
2741        os << "pression = " << Pression << endl;
2742        AfficherLog(&os, true);
2743    }
2744    else
2745    {
2746        os << "La pression atmosphérique est incorrecte !" << endl;
2747        ErreurLog(&os);
2748
2749        return false;
2750    }
2751
2752    key = "temperature";
2753
2754    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
2755    {
2756        Temperature = atof(value);
2757        SAFEDELETE_TAB(value);
2758        os << "température = " << Temperature << endl << endl;
2759        AfficherLog(&os, true);
2760    }
2761    else
2762    {
2763        ErreurLog("La température est incorrecte !\n");
2764
2765        return false;
2766    }
2767
2768    /////////////////////////////////////////
2769    // Rubrique alignement
2770
2771    section = "alignement";
2772
2773    key = "methode_alignement";
2774
2775    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
2776    {
2777        AfficherLog("methode d'alignement = " + (string)value + "\n", true);
2778        switch (value[0])
2779        {
2780        case 's' :
2781        case 'S' :
2782            MethodeAlignement = SIMPLE;
2783            break;
2784
2785        case 'a' :
2786        case 'A' :
2787            MethodeAlignement = AFFINE;
2788            break;
2789
2790        case 't' :
2791        case 'T' :
2792            MethodeAlignement = TAKI;
2793            break;
2794        }
2795
2796        SAFEDELETE_TAB(value);
2797    }
2798    else
2799    {
2800        ErreurLog("Le paramÚtre methode_alignement est incorrect !\n");
2801
2802        return false;
2803    }
2804
2805
2806
2807    /////////////////////////////////////////
2808    // Rubrique suivi
2809
2810    section = "suivi";
2811
2812    key = "mode";
2813
2814    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
2815    {
2816        Transit = (strstr(value, "transit") != NULL);
2817        AfficherLog("mode suivi = " + (string)value + "\n", true);
2818        SAFEDELETE_TAB(value);
2819    }
2820    else
2821    {
2822        ErreurLog("Le paramÚtre mode suivi est incorrect !\n");
2823
2824        return false;
2825    }
2826
2827
2828
2829    key = "delai_transit";
2830
2831    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
2832    {
2833        delaitransit = atoi(value);
2834        SAFEDELETE_TAB(value);
2835        os << "delai transit = " << delaitransit << " sec" << endl;
2836        AfficherLog(&os, true);
2837    }
2838    else
2839    {
2840        ErreurLog("Le paramÚtre delai_transit est incorrect !\n");
2841
2842        return false;
2843    }
2844
2845
2846    key = "delai_tracking";
2847
2848    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
2849    {
2850        delaitracking = atoi(value);
2851        SAFEDELETE_TAB(value);
2852        os << "delai tracking = " << delaitracking << " sec" << endl << endl;
2853        AfficherLog(&os, true);
2854    }
2855    else
2856    {
2857        ErreurLog("Le paramÚtre delai_tracking est incorrect !\n");
2858
2859        return false;
2860    }
2861
2862
2863    /////////////////////////////////////////
2864    // Rubrique divers
2865
2866    section = "divers";
2867
2868    key = "couleurs";
2869
2870    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
2871    {
2872        ChoixCouleurs=atoi(value);
2873        SAFEDELETE_TAB(value);
2874    }
2875    else
2876    {
2877        /*os << "Le paramÚtre couleurs est incorrect !" << endl;
2878        ErreurLog(os.str());
2879        return false;*/
2880    }
2881
2882    return true;
2883}
2884
2885
2886
2887
2888
2889
2890/**************************************************************************************
2891** Lecture des mouvements planifiés contenus dans le fichier fileName
2892** Ces fichiers de mouvement planifiés permettent des observations automatisées
2893** d'une liste d'objets (ou zone du ciel) pour lesquels on passe de l'un à l'autre
2894** en fonction de l'heure
2895**
2896***************************************************************************************/
2897
2898bool BAOcontrol::LectureFichierMouvements(string fileName)
2899{
2900    string section;
2901    string key;
2902    char * value   = NULL;
2903
2904    stringstream os;
2905    float a1, a2, a3;
2906
2907
2908    // Si le fichier n'existe pas -> on sort
2909
2910    if (!is_readable( fileName )) return false;
2911
2912    AfficherLog("Lecture du fichier " + fileName +"\n\n", true);
2913
2914    // initialisation du compteur nombre objets
2915
2916    numobjets = 1;
2917
2918    //Lecture de la rubrique ParamÚtres
2919
2920    section = "parametres";
2921
2922    // Mode transit ou tracking ?
2923
2924    key     = "mode";
2925
2926    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
2927    {
2928        Transit = ( strstr(value, "transit") != NULL);
2929        // il faut détruire les tableaux de caratÚres qui sont crées
2930        // dans la fonction ReadINI
2931        SAFEDELETE_TAB(value);
2932
2933        if (Transit) AfficherLog("Mode transit activé.\n", true);
2934        else AfficherLog("Mode tracking activé.\n", true);
2935    }
2936    else
2937    {
2938        ErreurLog("Le parametre mode est incorrect.\n");
2939
2940        return false;
2941    }
2942
2943    // Les coordonnées sont-elles dans le systÚme de coordonnées J2000 ?
2944
2945    key = "J2000";
2946
2947    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
2948    {
2949        J2000 = ( strstr(value, "on") != NULL);
2950
2951        SAFEDELETE_TAB(value);
2952
2953        if (J2000) AfficherLog("Mode J2000 activé.\n\n", true);
2954        else AfficherLog("Mode J2000 désactivé.\n\n", true);
2955    }
2956    else
2957    {
2958        ErreurLog("Le parametre J2000 est incorrect.\n");
2959
2960        return false;
2961    }
2962
2963    // Lecture de la liste des observations
2964
2965    section = "objet 1";
2966    key     = "date";
2967
2968
2969    while ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
2970            && (numobjets<MAXOBJETS))
2971    {
2972        os << "object n°" << numobjets << endl;
2973        AfficherLog(&os, true);
2974
2975        SAFEDELETE_TAB(value);
2976
2977
2978        // Lecture de la date et de l'heure de l'observation
2979
2980        key = "date";
2981
2982        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
2983                && (Decomposition(value, 3, &a1, &a2, &a3)))
2984        {
2985            AfficherLog("Date du début de l'observation : le " + (string)value, true);
2986            SAFEDELETE_TAB(value);
2987
2988            objets[numobjets].JJ = CalculJJ(a3, a2, a1, 0.0);
2989        }
2990        else
2991        {
2992            os << "La date de la rubrique [objet " << numobjets << "] est incorrecte !" << endl;
2993            ErreurLog(&os);
2994
2995            return false;
2996        }
2997
2998        key = "heure";
2999
3000        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
3001                && (Decomposition(value, 2, &a1, &a2, &a3)))
3002        {
3003            AfficherLog(" à " + (string)value, true) ;
3004            SAFEDELETE_TAB(value);
3005
3006
3007            objets[numobjets].JJ += ( a1 + a2 / 60.0 + a3 / 3600.0 ) / 24.0;
3008
3009            os << " TU  -> JJ=" << fixed << objets[numobjets].JJ << scientific << endl;
3010
3011            AfficherLog(&os, true);
3012
3013            for (int i=1; i<numobjets; i++)
3014            {
3015                if ( objets[i].JJ == objets[numobjets].JJ )
3016                {
3017                    os << "Attention, les observations des objets " << i << " et ";
3018                    os << numobjets << " sont définies à la même date !" << endl;
3019                    ErreurLog(&os);
3020                }
3021
3022                if ( objets[i].JJ + objets[i].Duree / 3600 / 24.0 > objets[numobjets].JJ )
3023                {
3024                    os << "Attention, les observations des objets " << i << " et " ;
3025                    os << numobjets << " se chevauchent !" << endl;
3026                    ErreurLog(&os);
3027                }
3028            }
3029        }
3030        else
3031        {
3032            os << "L'heure de la rubrique [objet " << numobjets << "] est incorrecte !" << endl;
3033            ErreurLog(&os);
3034
3035            return false;
3036        }
3037
3038
3039        // Lecture de la durée de l'observation
3040
3041        key = "duree";
3042
3043        objets[numobjets].Duree=0.0;
3044
3045        if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
3046        {
3047            AfficherLog("Durée de l'observation : " + (string)value + " secondes\n", true);
3048            objets[numobjets].Duree=atof(value);
3049            SAFEDELETE_TAB(value);
3050        }
3051        else
3052        {
3053            os << "La duree d'observation de la rubrique [objet " << numobjets << "] est incorrecte !\n";
3054            ErreurLog(&os);
3055
3056            return false;
3057        }
3058
3059        // Lecture de l'ascension droite de l'objet
3060
3061        key = "ad";
3062
3063        objets[numobjets].ad = "";
3064
3065        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
3066                && (Decomposition(value, 2, NULL, NULL, NULL)))
3067        {
3068            AfficherLog("Ascension droite de l'objet : " + (string)value + "\n", true);
3069            objets[numobjets].ad = value;
3070            SAFEDELETE_TAB(value);
3071        }
3072        else
3073        {
3074            os << "L'ascension droite de la rubrique [objet " << numobjets << "] est incorrecte !";
3075            os << endl;
3076            ErreurLog(&os);
3077
3078            return false;
3079        }
3080
3081        // Lecture de la déclinaison de l'objet
3082
3083        key = "de";
3084
3085        objets[numobjets].de = "";
3086
3087        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
3088                && (Decomposition(value, 0, NULL, NULL, NULL)))
3089        {
3090            AfficherLog("Déclinaison de l'objet : " + (string)value + "\n\n", true);
3091            objets[numobjets].de = value;
3092            SAFEDELETE_TAB(value);
3093        }
3094        else
3095        {
3096            os << "La déclinaison de la rubrique [objet " << numobjets << "] est incorrecte !";
3097            os << endl;
3098            ErreurLog(&os);
3099
3100            return false;
3101        }
3102
3103        objets[numobjets].exec = false;
3104
3105        // On passe à l'objet suivant
3106
3107        numobjets++;
3108
3109        os << "objet "<< numobjets;
3110
3111        section = os.str();
3112
3113        os.str("");
3114    }
3115
3116    SAFEDELETE_TAB(value);
3117
3118    return true;
3119}
3120
3121
3122/**************************************************************************************
3123** chargement du catalogue d'étoiles nécessaire à la procédure d'alignement
3124**
3125***************************************************************************************/
3126
3127bool BAOcontrol::ChargementCatalogueEtoiles(string fileName)
3128{
3129    string section;
3130    string key;
3131    char * value   = NULL;
3132
3133    stringstream os;
3134    float a1, a2, a3;
3135
3136    // Si le fichier n'existe pas -> on sort !
3137
3138    if (!is_readable(fileName)) return false;
3139
3140    AfficherLog("Chargement du catalogue d'étoiles : ", true);
3141
3142    UpdateTime();
3143
3144    numEtoiles = 0;
3145
3146    // Lecture des étoiles
3147
3148    section = "star 0";
3149    key     = "name";
3150
3151    while (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
3152    {
3153        // Nom de l'étoile
3154
3155        Etoiles[numEtoiles].nom = value;
3156        SAFEDELETE_TAB(value);
3157
3158        // On convertit le nom des étoiles en minuscules
3159
3160        for (uint i=0; i<strlen(Etoiles[numEtoiles].nom.c_str()); i++) Etoiles[numEtoiles].nom[i] = tolower(Etoiles[numEtoiles].nom[i]);
3161
3162
3163        //Constellation
3164
3165        key = "const";
3166
3167        readINI(section.c_str(), key.c_str(), &value, fileName.c_str());
3168
3169        Etoiles[numEtoiles].cons = value;
3170        SAFEDELETE_TAB(value);
3171
3172
3173        // Lecture des coordonnées de l'étoile
3174
3175        key = "ar";
3176
3177        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
3178                && (Decomposition(value, 2, &a1, &a2, &a3)))
3179        {
3180            SAFEDELETE_TAB(value);
3181
3182            Etoiles[numEtoiles].ad = (a1 + a2 / 60.0 + a3 / 3600.0) * 15.0 * Pidiv180;
3183        }
3184        else
3185        {
3186            os << "Les coordonnées AR de l'étoile " << numEtoiles << " sont incorrectes !" << endl;
3187            ErreurLog(&os);
3188
3189            return false;
3190        }
3191
3192        key = "de";
3193
3194        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
3195                && (Decomposition(value, 0, &a1, &a2, &a3)))
3196        {
3197            Etoiles[numEtoiles].de = (fabs(a1) + a2 / 60.0 + a3 / 3600.0 ) * Pidiv180;
3198
3199            if (value[0] == '-')  Etoiles[numEtoiles].de = - Etoiles[numEtoiles].de;
3200
3201            SAFEDELETE_TAB(value);
3202        }
3203        else
3204        {
3205            os << "Les coordonnées DE de l'étoile " << numEtoiles << " sont incorrectes !" << endl;
3206            ErreurLog(&os);
3207
3208            return false;
3209        }
3210
3211
3212        // Lecture de la durée de l'observation
3213
3214        key = "mag";
3215
3216        if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
3217        {
3218            Etoiles[numEtoiles].mag = atof(value);
3219            SAFEDELETE_TAB(value);
3220        }
3221        else
3222        {
3223            os << "La magnitude de l'étoile " << numEtoiles << " est incorrecte !\n";
3224            ErreurLog(&os);
3225
3226            return false;
3227        }
3228
3229
3230        // Passage du repÚre J2000 à l'écliptique et à l'équinoxe liée à la date de l'observation
3231
3232        Precession        (&Etoiles[numEtoiles].ad, &Etoiles[numEtoiles].de);
3233        NutationEtoile    (&Etoiles[numEtoiles].ad, &Etoiles[numEtoiles].de);
3234        AberrationAnnuelle(&Etoiles[numEtoiles].ad, &Etoiles[numEtoiles].de);
3235
3236
3237        // On passe à l'objet suivant
3238
3239        numEtoiles++;
3240
3241        key     = "name";
3242
3243        os << "star "<< numEtoiles;
3244
3245        section = os.str();
3246
3247        os.str("");
3248    }
3249
3250    if (value) SAFEDELETE_TAB(value);
3251
3252    os << numEtoiles-1 << " étoiles chargées.\n\n";
3253
3254    AfficherLog(os.str(), true);
3255
3256    return true;
3257}
3258
3259
3260
3261
3262/**************************************************************************************
3263** Routine principale
3264***************************************************************************************/
3265
3266int BAOcontrol::init(int argc, char **argv)
3267{
3268    string chaine;
3269
3270
3271    // gestion au démarrage des paramÚtres en ligne de commande
3272
3273    if ( argc >1 )
3274    {
3275        if (strstr(argv[1], "-h")!=NULL)
3276        {
3277            cout << "usage :\n \
3278       BAOControl -h ou --help : affiche l'aide\n \
3279       BAOControl -r FileName : exécute les mouvements définis dans le fichier FileName\n\n";
3280
3281            return 0;
3282        }
3283    }
3284
3285    if (argc == 1)  cout << "Tapez help pour obtenir la liste des commandes disponibles.\n" << endl << endl;
3286
3287
3288    // On lance le thread pour gérer la fenêtre graphique
3289    // la communication avec indi_BAO et le suivi des objets
3290
3291
3292
3293    // si on a utilisé l'option -r en ligne de commande
3294    // alors on charge et on exécute le fichier de mouvements
3295
3296    if (argc == 3)
3297    {
3298        if (strstr(argv[1], "-r")!=NULL)
3299        {
3300            exitrun=true;
3301
3302            Run(argv[2]);
3303
3304            // on attend ici la fin de l'exécution du fichier de mouvements
3305
3306            do
3307            {
3308
3309            } while (NoExit);
3310        }
3311        else
3312        {
3313            ErreurLog("Usage incorrect\n\n");
3314        }
3315    }
3316    else
3317    {
3318        // Saisie et décodage des commandes entrées par l'utilisateur
3319        /*
3320                do
3321                {
3322                    // Prompt
3323                    ChoixCouleurs==1 ? IDLog(blue2) : IDLog(blue1);
3324
3325                    cout << '>';
3326
3327                    // saisie
3328                    getline(cin, chaine);
3329
3330                    ChoixCouleurs==1 ? IDLog(grey1) : IDLog(grey2);
3331
3332                    AfficherLog(">" + chaine + "\n\n", false);
3333
3334                    // on met en minuscules
3335                    for (int i=0; i<chaine.size(); ++i) chaine[i] = tolower(chaine[i]);
3336
3337                    // on décode et exécute les commandes
3338                    DecodageEntreesUtilisateur(chaine);
3339
3340                }
3341                while (NoExit);
3342
3343                pthread_join(th1 ,NULL);*/
3344    }
3345
3346    return 0;
3347}
3348
3349
3350
3351
3352/**************************************************************************************
3353** Le fichier file existe-t-il et n'est-il pas vide ?
3354**
3355**************************************************************************************/
3356
3357bool BAOcontrol::is_readable( const string & file )
3358{
3359    ifstream fichier( file.c_str() );
3360    if (fichier.fail()) return false;
3361
3362    // sauvegarder la position courante
3363
3364    // long pos = fichier.tellg();
3365
3366    // se placer en fin de fichier
3367
3368    fichier.seekg( 0 , ios_base::end );
3369
3370    // récupérer la nouvelle position = la taille du fichier
3371
3372    long size = fichier.tellg();
3373
3374    return (size > 0);
3375}
Note: See TracBrowser for help on using the repository browser.