source: BAORadio/libindi/libindi/Indi_Stellarium/src/ServerBAO.cpp @ 623

Last change on this file since 623 was 623, checked in by frichard, 13 years ago
File size: 32.9 KB
Line 
1/*
2The stellarium telescope library helps building
3telescope server programs, that can communicate with stellarium
4by means of the stellarium TCP telescope protocol.
5It also contains smaple server classes (dummy, Meade LX200).
6
7Author and Copyright of this file and of the stellarium telescope library:
8Johannes Gajdosik, 2006
9
10This library is free software; you can redistribute it and/or
11modify it under the terms of the GNU Lesser General Public
12License as published by the Free Software Foundation; either
13version 2.1 of the License, or (at your option) any later version.
14
15This library is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18Lesser General Public License for more details.
19
20You should have received a copy of the GNU Lesser General Public
21License along with this library; if not, write to the Free Software
22Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23*/
24
25#include "ServerBAO.hpp"
26#include "Socket.hpp" // GetNow
27
28#include <math.h>
29
30ServerDummy::ServerDummy(int port)
31            :Server(port)
32{
33        last_pos[0] = current_pos[0] = desired_pos[0] = 1.0;
34        last_pos[1] = current_pos[1] = desired_pos[1] = 0.0;
35        last_pos[2] = current_pos[2] = desired_pos[2] = 0.0;
36        next_pos_time = -0x8000000000000000LL;
37
38
39        float a1, a2, a3;
40
41        // Le choix de la couleur des caractÚres est adapté pour une fenêtre de terminal
42        // ayant un fond blanc. pour un fond noir, mettre couleurs=2 dans le fichier params
43
44        ChoixCouleurs=1;
45
46
47        Affiche("\n\n\n\n\n \
48     ******************************************\n \
49     *           Serveur Stellarium           *\n \
50     * Laboratoire de l'Accélérateur Linéaire *\n \
51     *                                        *\n \
52     *             v0.1  20/08/2011           *\n \
53     *        franckrichard033@gmail.com      *\n \
54     ******************************************\n\n\n", true);
55
56        //Initialisation des variables globales et des pointeurs
57
58
59        delaitransit  = 0;
60        delaitracking = 0;
61        lognum        = 0;
62        numAntenne    = 0;
63        numobjets     = 0;
64        runnum        = 1;
65
66        Pression      = 1013.0;
67        Temperature   = 10.0;
68
69        NoExit        = true;
70        Transit       = false;
71        run           = false;
72        exitrun       = false;
73
74        fd            = NULL;
75        client_socket = NULL;
76
77        // chaines de caractÚres et tableaux
78
79        LatitudeChar  = "";
80        LongitudeChar = "";
81        Serveur       = "";
82        Port          = "";
83
84        Antennes      = new DefAntenne[MAXANTENNES];
85        objets        = new DefObjets[MAXOBJETS];
86
87        //on initalise aussi les tableaux
88
89        for (int i=0; i<MAXANTENNES; i++)
90        {
91            Antennes[i].ok=0;
92            Antennes[i].ip=0;
93        }
94
95        for (int i=0; i<MAXOBJETS; i++)
96        {
97            objets[i].JJ=0;
98            objets[i].exec=false;
99        }
100
101        // Chargement du fichier contenant les paramÚtres
102
103        if (!ChargementParametres("params"))
104        {
105            Erreur("Le fichier de configuration 'params' contient des erreurs ou n'existe pas.\n \
106            Merci de vérifier.\n\n");
107            exit(1);
108        }
109
110        // Conversion de la latitude et de la longitude en radians
111
112        Decomposition(LatitudeChar, 0, &a1, &a2, &a3);
113
114        double Latitude = (a1 + a2 / 60.0 + a3 / 3600.0) * Pidiv180;
115
116        Decomposition(LongitudeChar, 1, &a1, &a2, &a3);
117
118        double Longitude = Pi2 - ( a1 + a2 / 60.0 + a3 / 3600.0 ) * Pidiv180;
119
120        // Transfert de la latitude, longitude, pression, température à la classe Astro
121
122        DefinirLongitudeLatitude(Longitude, Latitude);
123
124        DefinirPressionTemp(Pression, Temperature);
125
126        // Ouverture du socket avec indi_BAO
127
128        client_socket = new ClientSocket("localhost", atoi(Port.c_str()) );
129
130        // On se connecte au pilote indi_BAO
131
132        Connect(true);
133
134        // On lance la fenêtre graphique
135
136        initialiserFenetre();
137
138        XSelectInput(d,w, ExposureMask );
139}
140
141void ServerDummy::step(long long int timeout_micros)
142{
143
144  if (last_pos[0]!=current_pos[0] || last_pos[1]!=current_pos[1] || last_pos[2]!=current_pos[2])
145  {
146                current_pos[0] = desired_pos[0];
147                        current_pos[1] = desired_pos[1];
148                        current_pos[2] = desired_pos[2];
149                       
150                const double ra = atan2(current_pos[1],current_pos[0]);
151                const double dec = atan2(current_pos[2],
152                                         sqrt(current_pos[0]*current_pos[0]+current_pos[1]*current_pos[1]));
153               
154                        //On actualise le jour julien et le temps sidéral local
155               
156                Goto(DHMS(VerifAngle(ra)*180.0/M_PI, true), DHMS(dec*180.0/M_PI, false), Transit, true);
157               
158                last_pos[0] = current_pos[0];
159                        last_pos[1] = current_pos[1];
160                        last_pos[2] = current_pos[2];
161  }
162
163    Update();
164
165   
166
167    // on lit et affiche la réponse des microcontrolleurs
168
169    LireReponse();
170
171    Dessiner();
172   
173       
174       
175
176       
177        Server::step(timeout_micros);
178}
179
180void ServerDummy::gotoReceived(unsigned int ra_int, int dec_int)
181{
182        const double ra = ra_int*(M_PI/(unsigned int)0x80000000);
183        const double dec = dec_int*(M_PI/(unsigned int)0x80000000);
184        const double cdec = cos(dec);
185        desired_pos[0] = cos(ra)*cdec;
186        desired_pos[1] = sin(ra)*cdec;
187        desired_pos[2] = sin(dec);
188}
189
190
191/**************************************************************************************
192** Affiche le message à l'écran (si AfficheEcran==true) et le sauvegarde dans le fichier
193** BAOControl.log
194***************************************************************************************/
195
196void ServerDummy::Affiche(string Message, bool AfficheEcran)
197{
198    FILE *pFile = NULL;
199
200    if ( (pFile = fopen ("BAOcontrol.log", "a")) != NULL)
201    {
202        if (AfficheEcran) cout << Message;
203
204        fprintf (pFile, Message.c_str());
205
206        fclose (pFile);
207    }
208}
209
210void ServerDummy::Affiche(stringstream *Message, bool AfficheEcran)
211{
212    Affiche(Message->str(), AfficheEcran);
213
214    // on efface le buffer
215
216    Message->str("");
217}
218
219
220/**************************************************************************************
221** Affiche les messages d'erreur en rouge
222***************************************************************************************/
223
224void ServerDummy::Erreur(string chaine)
225{
226    ChoixCouleurs==1 ? cout << red1  : cout << red2;
227    Affiche(chaine, true);
228    ChoixCouleurs==1 ? cout << grey1 : cout << grey2;
229}
230
231void ServerDummy::Erreur(stringstream *Message)
232{
233    Erreur(Message->str());
234
235    // on efface le buffer
236
237    Message->str("");
238}
239
240
241/**************************************************************************************
242** Initialise la fenêtre graphique
243***************************************************************************************/
244
245void ServerDummy::initialiserFenetre()
246{
247    XGCValues gcv;
248
249    // contacte le serveur graphique
250
251    if ((d = XOpenDisplay(getenv("DISPLAY"))) == NULL)
252    {
253        Erreur("Impossible de contacter le serveur\n\n");
254        exit(1);
255    }
256
257    // crée une fenêtre
258
259    w = XCreateSimpleWindow(d, RootWindow(d, DefaultScreen(d)),
260                            0, 0, larg_fenetre, haut_fenetre,
261                            2, BlackPixel(d, DefaultScreen(d)),
262                            WhitePixel(d, DefaultScreen(d)));
263
264    // Création du double buffer
265
266    db = XCreatePixmap(d, w, larg_fenetre, haut_fenetre, DefaultDepth(d, DefaultScreen(d)));
267
268    // Chargement de la police de caractÚres
269
270    if ((fd = XLoadQueryFont(d, "fixed")) == NULL)
271    {
272        Erreur("Impossible de charger la police fixed\n\n");
273        exit(1);
274    }
275
276    // Création des couleurs
277
278    gcv.font = fd->fid;
279    gcv.foreground = BlackPixel(d, DefaultScreen(d));
280    noir = XCreateGC(d, w, GCFont | GCForeground, &gcv);
281
282    gcv.foreground = 200*255;
283    vert = XCreateGC(d, w, GCFont | GCForeground, &gcv);
284
285    gcv.foreground = 255*256*256;
286    rouge = XCreateGC(d, w, GCFont | GCForeground, &gcv);
287
288    gcv.foreground = 200*256*256+200*256+200;
289    gris = XCreateGC(d, w, GCFont | GCForeground, &gcv);
290
291    // Affichage de fenêtre
292
293    XMapWindow(d, w);
294}
295
296
297/**************************************************************************************
298** Dessine les éléments dans la fenêtre graphique
299***************************************************************************************/
300
301void ServerDummy::Dessiner()
302{
303    char *chaine;
304    GC color;
305
306    chaine = new char [100];
307
308    // On efface la fenêtre
309
310    XSetForeground(d, noir, WhitePixel(d, DefaultScreen(d)));
311    XFillRectangle(d, db, noir, 0, 0, larg_fenetre, haut_fenetre);
312    XSetForeground(d, noir, BlackPixel(d, DefaultScreen(d)));
313
314    // On récupÚre la date et l'heure contenue dans la classe astro (et le jour julien)
315
316    double h  = GetHeure();
317    double mi = GetMin();
318    double s  = GetSec();
319    double a  = GetAnnee();
320    double m  = GetMois();
321    double j  = GetJour();
322    double JJ = GetJJ();
323
324    // on évite les affichages de l'heure du genre 12:56:60 ou 24:00:00
325
326    if (s==60) {
327        s = 0;
328        mi++;
329        if (mi == 60) {
330            mi = 0;
331            h++;
332            if (h == 24) {
333                h = 0;
334                j++;
335            }
336        }
337    }
338
339    //affichage de la date et de l'heure
340
341    sprintf(chaine, "%02.0f:%02.0f:%02.1f TU    %02.0f/%02.0f/%04.0f    JJ=%10.5f",
342            h, mi, s, j, m, a, JJ);
343
344    XDrawString(d, db, noir, 10, 10, chaine, strlen(chaine));
345
346    //En cas d'exécution d'un fichier de mouvements, on affiche la prochaine étape
347
348    if (run)
349    {
350        sprintf(chaine, "Prochaine etape dans %4.1fs", (objets[runnum].JJ - JJ) * 3600.0 * 24.0);
351
352        if ((objets[runnum].JJ - JJ) * 3600.0 * 24.0 >= 0.0)
353            XDrawString(d, db, noir, 350, 10, chaine, strlen(chaine));
354    }
355
356    // affichage des cercles d'état
357    // vert = l'antenne fonctionne
358    // rouge = problÚme détecté sur l'antenne
359    // gris = antenne non connectée
360
361    for (int i=0; i <20; i++)
362    {
363        for (int j=0; j<2; j++)
364        {
365            switch (Antennes[20*j+i].ok)
366            {
367            case 1 :
368                color=vert;
369                break;
370            case 2 :
371                color=rouge;
372                break;
373            default:
374                color=gris;
375                break;
376            }
377
378            XFillArc(d, db ,color, 10+i*30, 20+j*30, 15, 15, 0, 360*64);
379            XDrawArc(d, db ,noir,  10+i*30, 20+j*30, 15, 15, 0, 360*64);
380        }
381    }
382
383
384    // Affichage des messages d'indi_BAO
385    // gÚre aussi le défilement
386
387    if (lognum>10)
388    {
389        for (int i=lognum-1; i>lognum-11; i--)
390        {
391            if ((logs[i].find("Err")!=string::npos)
392                    || (logs[i].find("ALERTE")!=string::npos)) color=rouge;
393            else color=vert;
394            XDrawString(d, db, color, 10, 9*12+(i-lognum+10)*12, logs[i].c_str(), strlen(logs[i].c_str()));
395        }
396    }
397    else
398    {
399        for (int i=0; i<lognum; i++)
400        {
401            if ((logs[i].find("Err")!=string::npos)
402                    || (logs[i].find("ALERTE")!=string::npos)) color=rouge;
403            else color=vert;
404            XDrawString(d, db, color, 10, 9*12+i*12, logs[i].c_str(), strlen(logs[i].c_str()));
405        }
406    }
407
408    // On affiche la copie de l'écran une fois que tout est dessiné
409    // on évite ainsi les scientillements de la fenêtre
410
411    XCopyArea(d, db, w, noir, 0, 0, larg_fenetre, haut_fenetre, 0, 0);
412
413    // On force le rafraichissement de l'écran
414
415    XFlush(d);
416
417    delete [] chaine;
418}
419
420
421/**************************************************************************************
422** Gestion des événements affectant la fenêtre graphique
423***************************************************************************************/
424
425void ServerDummy::rouler()
426{
427    XEvent e;
428
429    if (XCheckWindowEvent(d, w, ExposureMask, &e))
430    {
431        switch (e.type)
432        {
433        default:
434            //cout << "J'ai reçu un événement " <<  e.type << endl
435            break;
436        case Expose :
437            Dessiner();
438            break;
439        }
440    }
441}
442
443
444/**************************************************************************************
445** RécupÚre les messages envoyés par indi_BAO
446***************************************************************************************/
447
448void ServerDummy::LireReponse()
449{
450    string reponse, memreponse, decomp;
451    bool test=false;
452
453    *client_socket >> reponse;
454
455   // printf("%s\n", reponse.c_str());
456
457    do
458    {
459        if (reponse.find("message")!=string::npos)
460        {
461            // On ne garde que la partie intéressante
462            // La partie suivant "message="...
463            reponse = reponse.substr(reponse.find("message") + 9);
464
465            memreponse = reponse;
466
467            // ...jusqu'au "
468            reponse=reponse.substr(0, reponse.find("\""));
469
470            // On récupÚre l'adresse ip de l'antenne qui nous parle
471            // et on met à jour le tabmeau des états des antennes
472
473            if (reponse.find(". (Antennes connectees")!=string::npos)
474            {
475                decomp=reponse.substr(0, reponse.find(". (Antennes connectees"));
476                decomp=decomp.substr(decomp.rfind(".")+1);
477
478                // si cette antenne est déjà connectée, on change son état
479
480                for (int i=0; i<numAntenne; i++)
481                {
482                    if (atoi(decomp.c_str()) == Antennes[i].ip)
483                    {
484                        Antennes[i].ok=1;
485                        test=true;
486                        break;
487                    }
488                }
489
490                // ou si c'est une nouvelle antenne, on l'ajoute au tableau
491
492                if (!test)
493                {
494                    Antennes[numAntenne].ip = atoi(decomp.c_str());
495                    Antennes[numAntenne++].ok = 1;
496                }
497            }
498
499            // erreur sur une antenne -> on change son état dans la fenêtre
500
501            if  ((reponse.find("ALERTE antenne ")!=string::npos) ||
502                    (reponse.find("Erreur sur l antenne ")!=string::npos))
503            {
504                decomp = reponse.substr(0, reponse.find(" :"));
505                decomp = decomp.substr(decomp.rfind(".") + 1);
506
507                for (int i=0; i<numAntenne; i++)
508                {
509                    if (atoi(decomp.c_str()) == Antennes[i].ip)
510                    {
511                        Antennes[i].ok = 2;  // Erreur sur l'antenne i
512                    }
513                }
514            }
515
516            // On sauvegarde le message dans le tableau logs
517
518            stringstream os;
519
520            os << lognum << " : " << reponse;
521
522            Affiche(os.str() + "\n", false);
523
524            if (lognum<MAXLOG-1) logs[lognum++] = os.str();
525
526            reponse = memreponse;
527        }
528        else reponse="";
529
530
531    } while ( reponse !="" );
532
533     // on actualise la fenêtre
534
535        Dessiner();
536
537    // on envoie un message pour actualiser la fenêtre graphique
538
539    rouler();
540}
541
542
543/**************************************************************************************
544** Est-ce que la réponse du pilote indi_BAO est conforme à ce que l'on attendait ?
545***************************************************************************************/
546
547bool ServerDummy::VerifReponse(string reponseattendue)
548{
549    string reponse = "";
550    string memreponse = "";
551    int    duree = 0;
552    bool   test = false;
553
554    // TODO :La réponse du driver ne vient pas tout de suite et on peut recevoir
555    // des messages intermédiaires un peu étranges impliquant la fonction CONNECT, pourquoi ?
556    // Là on lit les messages trois fois de suite pour essayer de voir passer le bon
557    // Essayer de voir si on ne peut pas faire mieux...
558
559    for (int i=0; i<3 ;i++)
560    {
561        do
562        {
563            usleep(1000); // attendre 1 ms pour laisser le temps au pilote indi_BAO de répondre
564
565            *client_socket >> reponse;
566
567            duree++;
568        }
569        while (reponse.length() == 0 && duree<10 ); // on attend un message pendant 10 ms max
570
571        // on ajoute tous les messages reçus dans memmreponse
572        // ->intéressant pour le debug
573
574        memreponse += reponse;
575
576        if (reponse.find(reponseattendue) != string::npos)
577        {
578            test = true;
579            break;
580        }
581    }
582
583    if (!test)
584    {
585        // réponse inconnue -> une erreur ?
586
587        int pos = memreponse.find("message=");
588
589        if ( pos != (int)string::npos )
590        {
591            memreponse = memreponse.substr(pos + 9);
592
593            memreponse = memreponse.substr(0, memreponse.find("\""));
594
595            Erreur("Réponse du pilote indi_BAO :" + memreponse + "\n\n");
596        }
597
598        return false;
599    }
600
601    return true;
602}
603
604
605/**************************************************************************************
606** Calcul du jour julien et du temps sidéral local
607***************************************************************************************/
608
609void ServerDummy::Update()
610{
611    struct tm date;
612    time_t t;
613    struct timeval tv;
614    struct timezone tz;
615
616    // On récupÚre la date et l'heure depuis l'horloge du systÚme
617
618    time(&t);
619    date=*gmtime(&t);
620    gettimeofday(&tv, &tz);
621
622    double Annee = (double)date.tm_year + 1900.0;
623    double Mois  = (double)date.tm_mon + 1.0;
624    double Jour  = (double)date.tm_mday;
625    double Heu   = (double)date.tm_hour;
626    double Min   = (double)date.tm_min;
627    double Sec   = (double)date.tm_sec + tv.tv_usec / 1.0E6;
628    //double UTCP  = 0.0;//(double)date.tm_isdst;
629
630    /*Annee=2011;
631    Mois=6;
632    Jour=17;
633    Heu=15;
634    Min=53.0;
635    Sec=00.0;*/
636
637    // On actualise la date et l'heure dans la classe Astro
638
639    DefinirDateHeure(Annee, Mois, Jour, Heu, Min, Sec);
640
641
642    // On lance le calcul
643
644    CalculTSL();
645}
646
647
648
649
650
651/**************************************************************************************
652** Envoie la longitude et la latitude du lieu d'observation au pilote indi_BAO
653***************************************************************************************/
654
655bool ServerDummy::EnvoyerCoordGeographiques()
656{
657    // la communication avec le pilote indi_BAO
658    // se fait par l'envoie de petit fichier xml
659    // d'où le cÃŽté complexe des commandes
660
661    try
662    {
663        *client_socket << "<newNumberVector device=\"BAO\" name=\"GEOGRAPHIC_COORD\">";
664        *client_socket << "<oneNumber name=\"LAT\">";
665        *client_socket << LatitudeChar;
666        *client_socket << "</oneNumber>";
667        *client_socket << "<oneNumber name=\"LONG\">";
668        *client_socket << LongitudeChar;
669        *client_socket << "</oneNumber>";
670        *client_socket << "</newNumberVector>";
671
672        if (!VerifReponse("name=\"GEOGRAPHIC_COORD\" state=\"Ok\""))
673        {
674            Erreur("ERREUR fct EnvoyerCoordGeographiques : pas de réponse du pilote indi_BAO.\n\n");
675
676            return false;
677        }
678    }
679
680    // un problÚme ?
681
682    catch ( SocketException& e )
683    {
684        Erreur("Exception was caught:" + e.description() + "\n");
685        return false;
686    }
687
688    Affiche("Les coordonnées géographiques ont bien été envoyées au pilote indi_BAO\n\n", true);
689
690    return true;
691}
692
693
694
695/**************************************************************************************
696** Place les antennes en position de repos
697***************************************************************************************/
698
699bool ServerDummy::Park()
700{
701    try
702    {
703        *client_socket << "<newSwitchVector device=\"BAO\" name=\"\" >";
704        *client_socket << "<oneSwitch name=\"PARK\">";
705        *client_socket << "On";
706        *client_socket << "</oneSwitch>";
707        *client_socket << "</newSwitchVector>";
708
709        if (!VerifReponse("PARK OK"))
710        {
711            Erreur("La commande PARK a échoué.\n\n");;
712
713            return false;
714        }
715    }
716    catch ( SocketException& e)
717    {
718        Erreur("Exception was caught:" + e.description() + "\n");
719        return false;
720    }
721
722    Affiche("Le pilote indi_BAO a bien reçu la commande PARK.\n\n", true);
723
724    return true;
725}
726
727
728
729/**************************************************************************************
730** Annule le mouvement en cours
731***************************************************************************************/
732
733bool ServerDummy::Abort()
734{
735    try
736    {
737        *client_socket << "<newSwitchVector device=\"BAO\" name=\"ABORT_MOTION\" >";
738        *client_socket << "<oneSwitch name=\"ABORT\">";
739        *client_socket << "On";
740        *client_socket << "</oneSwitch>";
741        *client_socket << "</newSwitchVector>";
742
743        if (!VerifReponse("ABORT OK"))
744        {
745            Erreur("L'annulation a échoué.\n\n");
746
747            return false;
748        }
749    }
750    catch ( SocketException& e)
751    {
752        Erreur("Exception was caught:" + e.description() + "\n");
753        return false;
754    }
755
756    Affiche("Le pilote indi_BAO a bien reçu la commande ABORT.\n\n", true);
757
758    return true;
759}
760
761
762
763/**************************************************************************************
764** Diriger l'antenne vers les coordonnées ar et dec et suivre l'objet
765** en activant le mode transit ou tracking.
766** si J2000 == true, cela signifie que les coordonnées ar et dec sont données dans le
767** le systÚme de coordonnées J2000 (écliptique et équinoxe du 1 janvier 2000 à 0 h TU)
768** Des calculs supplémentaires (précession, nutation, abérration) sont alors nécessaires
769***************************************************************************************/
770
771bool ServerDummy::Goto(string ar, string dec, bool Transit, bool J2000)
772{
773    float  ar1, ar2, ar3;
774    float  dec1, dec2, dec3;
775    double arf, decf;
776
777
778
779     /*
780     //Pour les tests
781     ar="05:39:14.8";
782     dec="23:19:24.1";
783     printf("JJ=%10.10f\n", GetJJ());
784     J2000=true;
785     */
786
787    // Conversion de l'AD et de la déclinaison en radians
788
789    Decomposition(ar, 2, &ar1, &ar2, &ar3);
790    Decomposition(dec, 0, &dec1, &dec2, &dec3);
791
792    arf  = ( ar1  + ar2 / 60.0  + ar3 / 3600.0 ) * 15.0 * Pidiv180;
793    decf = ( fabs(dec1) + dec2 / 60.0 + dec3 / 3600.0 ) * Pidiv180;
794
795    if (dec[0]=='-') decf = -decf;
796
797    // calculs pupplémentaires pour se ramener
798    // à l'époque de l'observation
799
800    if (J2000)
801    {
802        Precession(&arf, &decf);
803        NutationEtoile(&arf, &decf);
804        AberrationAnnuelle(&arf, &decf);
805    }
806
807    // on réécrit l'ar et la dec dans le format d'indi_BAO
808
809    ar  = DHMS(arf * N180divPi, true);
810
811    dec = DHMS(decf * N180divPi, false);
812
813    // on en informe l'utilisateur
814
815    Affiche("Coordonnées apparentes de l'objet :\n", true);
816
817    Affiche("AD=" + ar  + "   Dec=" + dec +"\n", true);
818
819
820    /*
821    //Tests
822    Azimut(arf, decf, &azi, &hau);
823
824    hau=RefractionAtmospherique(hau);
825
826    Affiche("Coordonnées rectangulaires liées au lieu d'observation :\n", true);
827
828    printf("Azimut = %s   Hauteur = %s\n", DHMS(azi*N180divPi,false).c_str(), DHMS(hau*N180divPi, false).c_str());
829    */
830
831    // On transmet les coordonnées au pilote BAO
832
833    try
834    {
835        *client_socket << "<newSwitchVector device=\"BAO\" name=\"ON_COORD_SET\">";
836        *client_socket << "<oneSwitch name=\"TRANSIT\">";
837        if (Transit) *client_socket << "On";
838        else *client_socket << "Off";
839        *client_socket << "</oneSwitch>";
840
841        *client_socket << "<oneSwitch name=\"TRACKING\">";
842        if (Transit)  *client_socket << "Off";
843        else *client_socket << "On";
844        *client_socket << "</oneSwitch>";
845        *client_socket << "</newSwitchVector>";
846
847        if (!VerifReponse("name=\"ON_COORD_SET\""))
848        {
849            Erreur("Le changement de mode TRANSIT/TRACKING a échoué.\n\n");
850
851            return false;
852        }
853
854        *client_socket << "<newNumberVector device=\"BAO\" name=\"EQUATORIAL_EOD_COORD_REQUEST\">";
855        *client_socket << "<oneNumber name=\"RA\">";
856        *client_socket << ar;
857        *client_socket << "</oneNumber>";
858        *client_socket << "<oneNumber name=\"DEC\">";
859        *client_socket << dec;
860        *client_socket << "</oneNumber>";
861        *client_socket << "</newNumberVector>";
862
863        if (!VerifReponse("name=\"EQUATORIAL_EOD_COORD_REQUEST\""))
864        {
865            Erreur("Le transfert des coordonnées de l'objet a échoué.\n\n");
866
867            return false;
868        }
869    }
870    catch ( SocketException& e)
871    {
872        Erreur("Exception was caught:" + e.description() + "\n");
873        return false;
874    }
875
876    Affiche("Les nouvelles coordonnées AD=" + ar + " Dec=" + dec, true);
877    Affiche(" ont été envoyées au pilote indi_BAO.\n\n", true);
878    return true;
879}
880
881
882
883/**************************************************************************************
884** Se connecte ou se déconnecte au pilote indi_BAO
885***************************************************************************************/
886
887bool ServerDummy::Connect(bool connect)
888{
889    try
890    {
891        *client_socket << "<newSwitchVector device=\"BAO\" name=\"CONNECTION\">";
892
893        if (connect) *client_socket << "<oneSwitch name=\"CONNECT\">";
894        else *client_socket << "<oneSwitch name=\"DISCONNECT\">";
895
896        *client_socket << "On";
897        *client_socket << "</oneSwitch>";
898        *client_socket << "</newSwitchVector>";
899
900        if (connect)
901        {
902            if (!VerifReponse("BAORadio is online"))
903            {
904                Erreur("La connexion a échoué.\n\n");
905
906                return false;
907            }
908        }
909        else
910        {
911            if (!VerifReponse("BAORadio is offline"))
912            {
913                Erreur("La déconnexion a échoué.\n\n");
914
915                return false;
916            }
917        }
918    }
919
920    catch ( SocketException& e )
921    {
922        Erreur("Exception was caught:" + e.description() + "\n");
923        return false;
924    }
925
926    if (connect)
927    {
928        Affiche("La connexion a été établie avec le pilote indi_BAO.\n\n", true);
929
930        EnvoyerCoordGeographiques();
931    }
932    else
933    {
934        Affiche("BAOcontrol s'est bien déconnecté du pilote indi_BAO.\n\n", true);
935    }
936
937    return true;
938}
939
940
941
942
943
944
945/**************************************************************************************
946** Décomposition et vérification des dates, heures, AD et déclinaisons
947**
948** type = 0 -> Déclinaison/latitude
949** type = 1 -> longitude
950** type = 2 -> AD ou heure
951** type = 3 -> date
952**
953** Exemple de Decomposition("15:23:12", 2, a, b, c) retourne a=15, b=23, c=12
954** si la chaine a un format incorrect, la fct retourne false
955***************************************************************************************/
956
957bool ServerDummy::Decomposition(string chaine, char type, float *a1, float *a2, float *a3)
958{
959    string car, s;
960    float a, b, c;
961
962    // pour les heures et les coordonnées, on attend ":" comme caractÚre séparateur, sinon
963    // on attend d'avoir des "/" pour une date
964
965    (type==3) ? car="/" : car=":";
966
967    // Y a-t-il 2 caractÚres ':' ou '/' dans la chaine ?
968    // C'est indispensable dans tous les cas
969
970    int test=0;
971    for (int i=0; i<(int)chaine.length(); i++) if (chaine[i] == car[0]) test++;
972    if (test<2) return false;
973
974    // Extraction des trois nombres
975
976    s = chaine.substr(0, chaine.find(car));
977
978    a = atoi(s.c_str());
979
980    s = chaine.substr(chaine.find(car)+1, chaine.rfind(car) - chaine.find(car) - 1);
981
982    b = atoi(s.c_str());
983
984    s = chaine.substr(chaine.rfind(car)+1);
985
986    c = Arrondi(atof(s.c_str())*100.0)/100.0;
987
988    //vérification de la cohérence des infos contenues dans la chaine
989
990    if (type < 3 )
991    {
992        // pour une déclinaison
993        if ((type==0) && (a>90.0  || a<-90.0)) return false;
994        // pour une AD
995        if ((type==1) && (a>360.0 || a<0.0  )) return false;
996        // pour une heure
997        if ((type==2) && (a>23.0  || a<0.0  )) return false;
998        // pour les minutes
999        if (b<0.0 || b>59.0 ) return false;
1000        //pour les secondes
1001        if (c<0.0 || c>=60.0) return false;
1002    }
1003    else
1004    {
1005        //pour les jours
1006        if (a<0.0 || a>31.0) return false;
1007        //pour les mois
1008        if (b<0.0 || b>12.0) return false;
1009    }
1010
1011    if (a1!=NULL) *a1 = a;
1012    if (a2!=NULL) *a2 = b;
1013    if (a3!=NULL) *a3 = c;
1014
1015    return true;
1016}
1017
1018
1019
1020
1021
1022
1023/**************************************************************************************
1024** Lecteur d'un fichier ligne aprÚs ligne
1025** retourne -1 à la fin
1026***************************************************************************************/
1027
1028int ServerDummy::readline (FILE * pfile, char *tab)
1029{
1030    int nbchar = 0;
1031    char c;
1032
1033    while ((c = getc (pfile)) != '\n')
1034    {
1035        if (c == EOF)
1036        {
1037            break;
1038        }
1039        tab[nbchar++] = c;
1040    }
1041    tab[nbchar] = '\0';
1042
1043    while (nbchar>0 && tab[nbchar-1]==' ')
1044    {
1045        tab[--nbchar] = '\0';
1046    }
1047
1048    while (tab[0]==' ') for (int i=1; i<=nbchar; i++) tab[i-1] = tab[i];
1049
1050    if (c == EOF) nbchar=-1;
1051
1052    return (nbchar);
1053}
1054
1055
1056
1057/**************************************************************************************
1058** chargement des paramÚtres contenus dans le fichier params
1059***************************************************************************************/
1060
1061bool ServerDummy::ChargementParametres(string fileName)
1062{
1063    string section;
1064    string key;
1065    char * value;
1066    stringstream os;
1067
1068
1069
1070    Affiche("Lecture du fichier de configuration 'params' :\n\n", true);
1071
1072
1073    /////////////////////////////////////////
1074    // Rubrique Coodonnées géographiques
1075
1076    section = "coordonnees geographiques";
1077
1078    key = "latitude";
1079
1080    if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
1081            && (Decomposition(value, 0, NULL, NULL, NULL)))
1082    {
1083        LatitudeChar = (string)value;
1084        delete [] value;
1085        Affiche("latitude = " + LatitudeChar +"\n", true);
1086    }
1087    else
1088    {
1089        Erreur("La latitude est incorrecte !\n");
1090        return false;
1091    }
1092
1093
1094    key = "longitude";
1095
1096    if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
1097            && (Decomposition(value, 1, NULL, NULL, NULL)))
1098    {
1099        LongitudeChar = (string)value;
1100        delete [] value;
1101        Affiche("longitude = " + LongitudeChar +"\n\n", true);
1102    }
1103    else
1104    {
1105        Erreur("La longitude est incorrecte !\n");
1106        return false;
1107    }
1108
1109
1110    /////////////////////////////////////////
1111    // rubrique connexion
1112
1113    section = "connexion indi";
1114
1115    key = "serveur";
1116
1117    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
1118    {
1119        Serveur = (string)value;
1120        delete [] value;
1121        Affiche("serveur = " + Serveur +"\n", true);
1122    }
1123    else
1124    {
1125        Erreur("Nom du serveur invalide !\n");
1126        return false;
1127    }
1128
1129
1130    key = "port";
1131
1132    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
1133    {
1134        Port = (string)value;
1135        delete [] value;
1136        Affiche("port = " + Port +"\n\n", true);
1137    }
1138    else
1139    {
1140        Erreur("Numéro de port incorrect !\n");
1141        return false;
1142    }
1143
1144
1145    /////////////////////////////////////////
1146    // Rubrique paramÚtres de l'atmosphÚre
1147
1148    section = "atmosphere";
1149
1150    key = "pression";
1151
1152    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
1153    {
1154        Pression = atof(value);
1155        delete [] value;
1156        os << "pression = " << Pression << endl;
1157        Affiche(&os, true);
1158    }
1159    else
1160    {
1161        os << "La pression atmosph&rique est incorrecte !" << endl;
1162        Erreur(&os);
1163        return false;
1164    }
1165
1166    key = "temperature";
1167
1168    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
1169    {
1170        Temperature=atof(value);
1171        delete [] value;
1172        os << "température = " << Temperature << endl << endl;
1173        Affiche(&os, true);
1174    }
1175    else
1176    {
1177        Erreur("La température est incorrecte !\n");
1178        return false;
1179    }
1180
1181
1182    /////////////////////////////////////////
1183    // Rubrique suivi
1184
1185    section = "suivi";
1186
1187    key = "mode";
1188
1189    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
1190    {
1191        Transit = (strstr(value, "transit") != NULL);
1192        Affiche("mode suivi = " + (string)value + "\n", true);
1193        delete [] value;
1194    }
1195    else
1196    {
1197        Erreur("Le paramÚtre mode est incorrect !\n");
1198        return false;
1199    }
1200
1201
1202
1203    key = "delai_transit";
1204
1205    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
1206    {
1207        delaitransit=atoi(value);
1208        delete [] value;
1209        os << "delai transit = " << delaitransit << " sec" << endl;
1210        Affiche(&os, true);
1211    }
1212    else
1213    {
1214        Erreur("Le paramÚtre delai_transit est incorrect !\n");
1215        return false;
1216    }
1217
1218
1219    key = "delai_tracking";
1220
1221    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
1222    {
1223        delaitracking=atoi(value);
1224        delete [] value;
1225        os << "delai tracking = " << delaitracking << " sec" << endl << endl;
1226        Affiche(&os, true);
1227    }
1228    else
1229    {
1230        Erreur("Le paramÚtre delai_tracking est incorrect !\n");
1231        return false;
1232    }
1233
1234
1235    /////////////////////////////////////////
1236    // Rubrique divers
1237
1238    section = "divers";
1239
1240    key = "couleurs";
1241
1242    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
1243    {
1244        ChoixCouleurs=atoi(value);
1245        delete [] value;
1246    }
1247    else
1248    {
1249        /*os << "Le paramÚtre couleurs est incorrect !" << endl;
1250        Erreur(os.str());
1251        return false;*/
1252    }
1253
1254    return true;
1255}
1256
1257
Note: See TracBrowser for help on using the repository browser.