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

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