Changeset 642


Ignore:
Timestamp:
Feb 24, 2012, 12:37:36 PM (12 years ago)
Author:
frichard
Message:

-Alignement des antennes
-Version 0.0.9 de libindi

Location:
BAORadio/libindi/libindi
Files:
67 edited

Legend:

Unmodified
Added
Removed
  • BAORadio/libindi/libindi/BAOControl/Makefile

    r619 r642  
    1 # Makefile for the socket programming example
     1# Makefile
    22#
    33
     
    77CXXFLAGS = -g
    88
    9 BAOcontrol_objects =  main.o baocontrol.o ClientSocket.o Socket.o filetools.o exception.o
    10 
     9BAOcontrol_objects =  main.o baocontrol.o
    1110
    1211all : BAOcontrol
     
    1413
    1514BAOcontrol: $(BAOcontrol_objects)
    16         g++ $(CXXFLAGS) -c -o ../BAOControl/astro.o ../drivers/telescope/astro.cpp
    17         g++ $(CXXFLAGS) -o BAOcontrol $(BAOcontrol_objects) astro.o -lpthread -lX11
     15        g++ $(CXXFLAGS) -c -o ../BAOControl/astro.o ../communs/astro.cpp
     16        g++ $(CXXFLAGS) -c -o ../BAOControl/exception.o ../communs/exception.cpp
     17        g++ $(CXXFLAGS) -c -o ../BAOControl/filetools.o ../communs/filetools.cpp
     18        g++ $(CXXFLAGS) -c -o ../BAOControl/Socket.o ../communs/Socket.cpp
     19        g++ $(CXXFLAGS) -c -o ../BAOControl/ClientSocket.o ../communs/ClientSocket.cpp
     20        g++ $(CXXFLAGS) -c -o ../BAOControl/logs.o ../communs/logs.cpp
     21        g++ $(CXXFLAGS) -c -o ../BAOControl/alignement.o ../communs/alignement.cpp
     22        g++ $(CXXFLAGS) -o BAOcontrol $(BAOcontrol_objects) astro.o exception.o filetools.o Socket.o ClientSocket.o logs.o alignement.o -lpthread -lX11
    1823
    19 Socket:  Socket.cpp
    20 ClientSocket: ClientSocket.cpp
    2124baocontrol: baocontrol.cpp
    22 filetools: filetools.cpp
    23 exception: exception.c
    2425main: main.cpp
    2526
  • BAORadio/libindi/libindi/BAOControl/baocontrol.cpp

    r619 r642  
    44/* Franck RICHARD             */
    55/* franckrichard033@gmail.com */
    6 /* Décembre 2011              */
     6/* Février 2012               */
    77/******************************/
    88
    99
    1010#include "baocontrol.h"
    11 #include <termios.h>
    12 #include <unistd.h>
     11
    1312
    1413
    1514
    1615/**************************************************************************************
    17 **Constructeur
     16** Constructeur de la classe BAOcontrol
     17**
    1818***************************************************************************************/
    1919
     
    2323
    2424    // Le choix de la couleur des caractÚres est adapté pour une fenêtre de terminal
    25     // ayant un fond blanc. pour un fond noir, mettre couleurs=2 dans le fichier params
     25    // ayant un fond blanc. pour un fond noir, mettre couleurs = 2 dans le fichier params
    2626
    2727    ChoixCouleurs=1;
    2828
    29 
    30     Affiche("\n\n\n\n\n \
     29    //Affichage de la version du porgramme
     30
     31    AfficherLog("\n\n\n\n\n \
    3132 ******************************************\n \
    3233 *             BAORadio Control           *\n \
    3334 * Laboratoire de l'Accélérateur Linéaire *\n \
    3435 *                                        *\n \
    35  *             v0.4  02/12/2011           *\n \
     36 *             v0.5  23/02/2012           *\n \
    3637 *        franckrichard033@gmail.com      *\n \
    3738 ******************************************\n\n\n", true);
    3839
    39     //Initialisation des variables globales et des pointeurs
    40 
    41 
    42     delaitransit  = 0;
    43     delaitracking = 0;
    44     lognum        = 0;
    45     numAntennes   = 0;
    46     numobjets     = 0;
    47     runnum        = 1;
    48 
    49     Pression      = 1013.0;
    50     Temperature   = 10.0;
    51 
    52     NoExit        = true;
    53     Transit       = false;
    54     run           = false;
    55     exitrun       = false;
    56 
    57     fd            = NULL;
    58     client_socket = NULL;
     40
     41    // Initialisation des variables globales et des pointeurs
     42    // pour la signification des variables, voir baocontrol.h
     43
     44
     45    delaitransit           = 0;
     46    delaitracking          = 0;
     47    lognum                 = 0;
     48    numAntennes            = 0;
     49    numobjets              = 0;
     50    numEtoiles             = 0;
     51    runnum                 = 1;
     52
     53    MethodeAlignement      = SIMPLE;
     54
     55
     56    Pression               = 1013.0;
     57    Temperature            = 10.0;
     58
     59    NoExit                 = true;
     60    Transit                = false;
     61    run                    = false;
     62    exitrun                = false;
     63    ModificationAlignement = false;
     64
     65    fd                     = NULL;
     66    client_socket          = NULL;
    5967
    6068    // chaines de caractÚres et tableaux
    6169
    62     LatitudeChar  = "";
    63     LongitudeChar = "";
    64     Serveur       = "";
    65     Port          = "";
    66 
    67     Antennes      = new DefAntenne[MAXANTENNES];
    68     objets        = new DefObjets[MAXOBJETS];
    69 
    70     //on initalise aussi les tableaux
     70    LatitudeChar           = "";
     71    LongitudeChar          = "";
     72    Serveur                = "";
     73    Port                   = "";
     74
     75    Antennes               = new DefAntenne[ MAXANTENNES ];
     76    objets                 = new DefObjets [ MAXOBJETS ];
     77    Etoiles                = new DefEtoiles[ MAXETOILES] ;
     78
     79
     80    //on initalise aussi les structures
    7181
    7282    for (int i=0; i<MAXANTENNES; i++)
    7383    {
    74         Antennes[i].ok=0;
    75         Antennes[i].ip=0;
    76         Antennes[i].delta_az=0;
    77         Antennes[i].delta_ha=0;
     84        Antennes[i].ok = 0;
     85        Antennes[i].ip = 0;
     86
     87        Antennes[i].AlignementAntenne = new Alignement();
    7888    }
    7989
    8090    for (int i=0; i<MAXOBJETS; i++)
    8191    {
    82         objets[i].JJ=0;
    83         objets[i].exec=false;
    84     }
    85 
    86     // Chargement du fichier contenant les paramÚtres
    87 
    88     if (!ChargementParametres("params"))
    89     {
    90         Erreur("Le fichier de configuration 'params' contient des erreurs ou n'existe pas.\n \
    91         Merci de vérifier.\n\n");
     92        objets[i].JJ   = 0.0;
     93        objets[i].exec = false;
     94    }
     95
     96    for (int i=0; i<MAXETOILES; i++)
     97    {
     98        Etoiles[i].nom          = "";
     99        Etoiles[i].ad           = 0.0;
     100        Etoiles[i].de           = 0.0;
     101        Etoiles[i].az           = 0.0;
     102        Etoiles[i].ha           = 0.0;
     103        Etoiles[i].mag          = 0.0;
     104        Etoiles[i].selectionnee = false;
     105    }
     106
     107
     108    // Chargement du fichier contenant les paramÚtres de l'application BAOcontrol
     109    // La variable permet de récupérer le nom de l'utilisateur ayant ouvert la session sous linux
     110    // c'est dans le répertoire /home/USER/ que BAOcontrol cherche le fichier de paramÚtre baocontrol_params
     111
     112    if (!ChargementParametres("/home/" + (string)getenv("USER") + "/baocontrol_params"))
     113    {
     114        ErreurLog("Le fichier de configuration 'params' contient des erreurs ou n'existe pas.\n");
     115        ErreurLog("Il devrait se trouver dans le répertoire /home/" + (string)getenv("USER") +"\n");
     116        ErreurLog("Merci de vérifier...\n\n");
    92117        exit(1);
    93118    }
    94119
     120
    95121    // Conversion de la latitude et de la longitude en radians
    96122
     
    103129    double Longitude = Pi2 - ( a1 + a2 / 60.0 + a3 / 3600.0 ) * Pidiv180;
    104130
     131
    105132    // Transfert de la latitude, longitude, pression, température à la classe Astro
    106133
     
    108135
    109136    DefinirPressionTemp(Pression, Temperature);
     137
     138
     139    //Chargement du catalogue d'étoiles que l'on utilise pour l'alignement des antennes
     140
     141    if ( !ChargementCatalogueEtoiles("/home/" + (string)getenv("USER") + "/bao_catalogue.dat") )
     142    {
     143        ErreurLog("Le catalogue d'étoiles 'bao_catalogue' est introuvable.\n");
     144        ErreurLog("Il devrait se trouver dans le répertoire /home/" + (string)getenv("USER") +"\n");
     145        ErreurLog("Merci de vérifier...\n\n");
     146        exit(1);
     147    }
     148
    110149
    111150    // Ouverture du socket avec indi_BAO
     
    121160
    122161/**************************************************************************************
    123 ** Destructeur
     162** Destructeur de la classe BAOcontrol
     163**
    124164***************************************************************************************/
    125165
    126166BAOcontrol::~BAOcontrol()
    127167{
    128     // destruction des tableaux
    129    
     168    AfficherLog("\nNettoyage de la mémoire...\n\n", true);
     169
     170    // destruction des pointeurs et des tableaux
     171
     172    for (int i=0; i<MAXANTENNES; i++)
     173    {
     174        delete Antennes[i].AlignementAntenne;
     175    }
     176
    130177    delete [] Antennes;
    131178    delete [] objets;
    132 
    133     // destruction de la fenêtre graphique,des caractÚres
    134 
    135     if (d!=NULL)
     179    delete [] Etoiles;
     180
     181
     182    // destruction de la fenêtre graphique et des caractÚres
     183
     184    if ( d!=NULL )
    136185    {
    137186        XFreeGC(d, noir);
     
    150199
    151200
     201
    152202/**************************************************************************************
    153 ** Affiche le message à l'écran (si AfficheEcran==true) et le sauvegarde dans le fichier
    154 ** BAOControl.log
    155 ***************************************************************************************/
    156 
    157 void BAOcontrol::Affiche(string Message, bool AfficheEcran)
    158 {
    159     FILE *pFile = NULL;
    160 
    161     if ( (pFile = fopen ("BAOcontrol.log", "a")) != NULL)
    162     {
    163         if (AfficheEcran) cout << Message;
    164 
    165         fprintf (pFile, Message.c_str());
    166 
    167         fclose (pFile);
    168     }
    169 }
    170 
    171 void BAOcontrol::Affiche(stringstream *Message, bool AfficheEcran)
    172 {
    173     Affiche(Message->str(), AfficheEcran);
    174 
    175     // on efface le buffer
    176 
    177     Message->str("");
    178 }
    179 
    180 
    181 /**************************************************************************************
    182 ** Affiche les messages d'erreur en rouge
    183 ***************************************************************************************/
    184 
    185 void BAOcontrol::Erreur(string chaine)
    186 {
    187     ChoixCouleurs==1 ? cout << red1  : cout << red2;
    188     Affiche(chaine, true);
    189     ChoixCouleurs==1 ? cout << grey1 : cout << grey2;
    190 }
    191 
    192 void BAOcontrol::Erreur(stringstream *Message)
    193 {
    194     Erreur(Message->str());
    195 
    196     // on efface le buffer
    197 
    198     Message->str("");
    199 }
    200 
    201 
    202 /**************************************************************************************
    203 ** Initialise la fenêtre graphique
     203** Initialise la fenêtre graphique de BAOcontrol
     204**
    204205***************************************************************************************/
    205206
     
    212213    if ((d = XOpenDisplay(getenv("DISPLAY"))) == NULL)
    213214    {
    214         Erreur("Impossible de contacter le serveur\n\n");
     215        ErreurLog("Impossible de contacter le serveur graphique...\n\n");
    215216        exit(1);
    216217    }
     218
    217219
    218220    // crée une fenêtre
     
    223225                            WhitePixel(d, DefaultScreen(d)));
    224226
     227
    225228    // Création du double buffer
    226229
    227230    db = XCreatePixmap(d, w, larg_fenetre, haut_fenetre, DefaultDepth(d, DefaultScreen(d)));
    228231
     232
    229233    // Chargement de la police de caractÚres
    230234
    231235    if ((fd = XLoadQueryFont(d, "fixed")) == NULL)
    232236    {
    233         Erreur("Impossible de charger la police fixed\n\n");
     237        ErreurLog("Impossible de charger la police fixed...\n\n");
    234238        exit(1);
    235239    }
    236240
     241
    237242    // Création des couleurs
    238243
    239244    gcv.font = fd->fid;
     245
    240246    gcv.foreground = BlackPixel(d, DefaultScreen(d));
    241247    noir = XCreateGC(d, w, GCFont | GCForeground, &gcv);
    242248
    243     gcv.foreground = 200*255;
     249    gcv.foreground = 200 * 255;
    244250    vert = XCreateGC(d, w, GCFont | GCForeground, &gcv);
    245251
    246     gcv.foreground = 255*256*256;
     252    gcv.foreground = 255 * 256 * 256;
    247253    rouge = XCreateGC(d, w, GCFont | GCForeground, &gcv);
    248254
    249     gcv.foreground = 200*256*256+200*256+200;
     255    gcv.foreground = 200 * 256 * 256 + 200 * 256 + 200;
    250256    gris = XCreateGC(d, w, GCFont | GCForeground, &gcv);
    251257
    252     // Affichage de fenêtre
     258
     259    // Affichage de la fenêtre
    253260
    254261    XMapWindow(d, w);
     
    267274    chaine = new char [100];
    268275
     276
    269277    // On efface la fenêtre
    270278
    271     XSetForeground(d, noir, WhitePixel(d, DefaultScreen(d)));
    272     XFillRectangle(d, db, noir, 0, 0, larg_fenetre, haut_fenetre);
    273     XSetForeground(d, noir, BlackPixel(d, DefaultScreen(d)));
    274 
    275     // On récupÚre la date et l'heure contenue dans la classe astro (et le jour julien)
     279    XSetForeground( d, noir, WhitePixel(d, DefaultScreen(d)));
     280    XFillRectangle( d, db, noir, 0, 0, larg_fenetre, haut_fenetre);
     281    XSetForeground( d, noir, BlackPixel(d, DefaultScreen(d)));
     282
     283
     284    // On récupÚre la date et l'heure contenue dans la classe astro (ainsi que le jour julien)
    276285
    277286    double h  = GetHeure();
     
    282291    double j  = GetJour();
    283292    double JJ = GetJJ();
     293
    284294
    285295    // on évite les affichages de l'heure du genre 12:56:60 ou 24:00:00
     
    298308    }
    299309
     310
    300311    //affichage de la date et de l'heure
    301312
     
    305316    XDrawString(d, db, noir, 10, 10, chaine, strlen(chaine));
    306317
    307     //En cas d'exécution d'un fichier de mouvements, on affiche la prochaine étape
     318
     319    // En cas d'exécution d'un fichier de mouvements, on affiche la durée avant la prochaine étape
    308320
    309321    if (run)
     
    315327    }
    316328
    317     // affichage des cercles d'état
     329
     330    // affichage des cercles d'état des antennes
    318331    // vert = l'antenne fonctionne
    319332    // rouge = problÚme détecté sur l'antenne
     
    338351
    339352            XFillArc(d, db ,color, 10+i*30, 20+j*30, 15, 15, 0, 360*64);
     353
    340354            XDrawArc(d, db ,noir,  10+i*30, 20+j*30, 15, 15, 0, 360*64);
    341355        }
     
    343357
    344358
    345     // Affichage des messages d'indi_BAO
    346     // gÚre aussi le défilement
    347 
    348     if (lognum>10)
    349     {
    350         for (int i=lognum-1; i>lognum-11; i--)
     359    // Affichage des messages venant du serveur indi_BAO et récupérés par la fonction LireReponse()
     360    // Les messages d'erreurs sont affichés en rouge
     361
     362    for (int i=0; i<lognum; i++)
     363    {
     364        if (i>lognum-11)
    351365        {
    352366            if ((logs[i].find("Err")!=string::npos)
    353367                    || (logs[i].find("ALERTE")!=string::npos)) color=rouge;
    354368            else color=vert;
    355             XDrawString(d, db, color, 10, 9*12+(i-lognum+10)*12, logs[i].c_str(), strlen(logs[i].c_str()));
    356         }
    357     }
    358     else
    359     {
    360         for (int i=0; i<lognum; i++)
    361         {
    362             if ((logs[i].find("Err")!=string::npos)
    363                     || (logs[i].find("ALERTE")!=string::npos)) color=rouge;
    364             else color=vert;
    365             XDrawString(d, db, color, 10, 9*12+i*12, logs[i].c_str(), strlen(logs[i].c_str()));
    366         }
    367     }
    368 
    369     // On affiche la copie de l'écran une fois que tout est dessiné
    370     // on évite ainsi les scientillements de la fenêtre
     369            XDrawString(d, db, color, 10, (lognum>10)?9*12+(i-lognum+10)*12:9*12+i*12,
     370                        logs[i].c_str(), strlen(logs[i].c_str()));
     371        }
     372    }
     373
     374
     375    // On n'affiche la fenêtre graphique que lorsque tous les éléments ont été dessinés à l'intérieur
     376    // On évite ainsi le scientillement de la fenêtre...
    371377
    372378    XCopyArea(d, db, w, noir, 0, 0, larg_fenetre, haut_fenetre, 0, 0);
     379
    373380
    374381    // On force le rafraichissement de l'écran
     
    380387
    381388
     389
    382390/**************************************************************************************
    383391** Gestion des événements affectant la fenêtre graphique
     392**
    384393***************************************************************************************/
    385394
     
    403412
    404413
     414
    405415/**************************************************************************************
    406 ** RécupÚre les messages envoyés par indi_BAO
     416** RécupÚre les messages envoyés par le serveur indi_BAO
     417**
    407418***************************************************************************************/
    408419
     
    410421{
    411422    string reponse, memreponse, decomp;
    412     bool test=false;
     423
     424    bool test = false;
     425
     426    // on récupÚre les messages provenant d'indi_BAO
    413427
    414428    *client_socket >> reponse;
    415    
    416    // printf("%s\n", reponse.c_str());
    417429
    418430    do
    419431    {
    420         if (reponse.find("message")!=string::npos)
     432        // s'il contient le mot message (et vient donc d'indi_BAO)
     433
     434        if (reponse.find("message") != string::npos)
    421435        {
    422436            // On ne garde que la partie intéressante
    423             // La partie "message="...
     437            // La partie qui suit "message="...
     438
    424439            reponse = reponse.substr(reponse.find("message") + 9);
    425440
     441            //(on en garde une trace)
     442
    426443            memreponse = reponse;
    427444
    428             // ...jusqu'au "
    429             reponse=reponse.substr(0, reponse.find("\""));
     445            // ...on extrait le message jusqu'au caractÚre "
     446
     447            reponse = reponse.substr(0, reponse.find("\""));
    430448
    431449            // On récupÚre l'adresse ip de l'antenne qui nous parle
    432             // et on met à jour le tableau des états des antennes
     450            // et on met à jour le tableau des états de l'antenne correspondante
     451            // Dans les messages d'indi_BAO, l'adresse ip précÚde les mots "Antennes connectées"
    433452
    434453            if (reponse.find(". (Antennes connectees")!=string::npos)
     
    437456                decomp = decomp.substr(decomp.rfind(".")+1);
    438457
    439                 // si cette antenne est déjà connectée, on change son état
    440                
    441                 if (atoi(decomp.c_str())!=0) for (int i=0; i<numAntennes; i++)
    442                 {
    443                     if (atoi(decomp.c_str()) == Antennes[i].ip)
     458                // si cette antenne est déjà connectée, on change son état si nécessaire
     459
     460                if ( atoi(decomp.c_str()) != 0 ) for (int i=0; i<numAntennes; i++)
    444461                    {
    445                         Antennes[i].ok=1;
    446                         test=true;
    447                         break;
     462                        // on a trouvé l'antenne correspondante
     463
     464                        if (atoi(decomp.c_str()) == Antennes[i].ip)
     465                        {
     466                            Antennes[i].ok = 1;
     467                            test = true;
     468                            break;
     469                        }
    448470                    }
    449                 }
    450 
    451                 // ou si c'est une nouvelle antenne, on l'ajoute au tableau
     471
     472                // ou si c'est une nouvelle antenne, on l'ajoute au tableau Antennes
    452473
    453474                if (!test)
    454475                {
    455476                    Antennes[numAntennes].ip = atoi(decomp.c_str());
     477
    456478                    Antennes[numAntennes++].ok = 1;
    457479                }
     
    459481
    460482            // erreur sur une antenne -> on change son état dans la fenêtre
    461 
    462             if  ((reponse.find("ALERTE antenne ")!=string::npos) ||
    463                     (reponse.find("Erreur sur l antenne ")!=string::npos))
     483            // on trouve les erreurs dans les messages d'indi_BAO forumulée
     484            // de la façon suivnate: "ALERTE antenne" ou bien "Erreur sur l antenne"
     485
     486            if  ((reponse.find("ALERTE antenne ") != string::npos) ||
     487                    (reponse.find("Erreur sur l antenne ") != string::npos))
    464488            {
    465489                decomp = reponse.substr(0, reponse.find(" :"));
     
    468492                for (int i=0; i<numAntennes; i++)
    469493                {
     494                    // On identifie l'antenne dans le tableau Antennes et on change son état
     495
    470496                    if (atoi(decomp.c_str()) == Antennes[i].ip)
    471497                    {
     
    475501            }
    476502
    477             // On sauvegarde le message dans le tableau logs
     503            // On sauvegarde le message dans le fichier logs mais on ne l'affiche pas
    478504
    479505            stringstream os;
     
    481507            os << lognum << " : " << reponse;
    482508
    483             Affiche(os.str() + "\n", false);
    484 
    485             if (lognum<MAXLOG-1) logs[lognum++] = os.str();
     509            AfficherLog(os.str() + "\n", false);
     510
     511            if ( lognum < MAXLOG - 1 ) logs[ lognum++ ] = os.str();
    486512
    487513            reponse = memreponse;
    488         } 
    489         else reponse="";
    490          
    491 
    492     } while ( reponse !="" );
    493 
    494      // on actualise la fenêtre
    495 
    496         Dessiner();
     514        }
     515        else reponse = "";
     516
     517
     518    } while ( reponse != "" );
     519
     520    // on actualise la fenêtre
     521
     522    Dessiner();
    497523
    498524    // on envoie un message pour actualiser la fenêtre graphique
     
    505531/**************************************************************************************
    506532** Est-ce que la réponse du pilote indi_BAO est conforme à ce que l'on attendait ?
     533** Retourne true si c'est bonne
     534**
    507535***************************************************************************************/
    508536
     
    529557            duree++;
    530558        }
    531         while (reponse.length() == 0 && duree<10 ); // on attend un message pendant 10 ms max
     559        while (reponse.length() == 0 && duree < 20 ); // on attend un message pendant 10 ms max
    532560
    533561        // on ajoute tous les messages reçus dans memmreponse
     
    555583            memreponse = memreponse.substr(0, memreponse.find("\""));
    556584
    557             Erreur("Réponse du pilote indi_BAO :" + memreponse + "\n\n");
     585            ErreurLog("Réponse du pilote indi_BAO :" + memreponse + "\n\n");
    558586        }
    559587
     
    565593
    566594
     595
    567596/**************************************************************************************
    568597** Calcul du jour julien et du temps sidéral local
     598**
    569599***************************************************************************************/
    570600
    571 void BAOcontrol::Update()
     601void BAOcontrol::UpdateTime()
    572602{
     603    time_t t;
    573604    struct tm date;
    574     time_t t;
    575605    struct timeval tv;
    576     struct timezone tz;
    577606
    578607    // On récupÚre la date et l'heure depuis l'horloge du systÚme
     
    580609    time(&t);
    581610    date=*gmtime(&t);
    582     gettimeofday(&tv, &tz);
     611    gettimeofday(&tv, NULL);
    583612
    584613    double Annee = (double)date.tm_year + 1900.0;
     
    590619    double UTCP  = 0.0;//(double)date.tm_isdst;
    591620
    592     /*Annee=2011;
    593     Mois=6;
    594     Jour=17;
    595     Heu=15;
    596     Min=53.0;
    597     Sec=00.0;*/
    598 
    599621    // On actualise la date et l'heure dans la classe Astro
    600622
    601623    DefinirDateHeure(Annee, Mois, Jour, Heu, Min, Sec);
    602624
    603     // On lance les calculs
     625    // On lance les calculs (Temps sidéral local etc...)
    604626
    605627    CalculTSL();
     
    607629
    608630
     631
    609632/**************************************************************************************
    610633** gestion du thread permettant
    611 ** -l'exécution d'une liste de mouvements programmés
    612 ** -l'actualisation de la fenêtre graphique
    613 ** -la récupération des messages du pilote indi_BAO
     634** - l'exécution d'une liste de mouvements programmés
     635** - l'actualisation de la fenêtre graphique
     636** - la récupération des messages du pilote indi_BAO
     637**
    614638***************************************************************************************/
    615639
     
    617641{
    618642    stringstream os;
    619 
    620     // Tant ue l'utilisateur n'a pas taper la commande 'exit'
     643    struct timeval tv;
     644
     645    // Tant que l'utilisateur n'a pas tapé la commande 'exit'
    621646    while (NoExit)
    622647    {
    623         //On actualise le jour julien et le temps sidéral local
    624 
    625         Update();
     648        // On actualise le jour julien et le temps sidéral local
     649
     650        UpdateTime();
    626651
    627652        // On récupÚre le jour julien
     
    632657        // Faut-il executer un fichier de mouvements ?
    633658
    634         if (run && numobjets>1 && runnum<numobjets)
    635         {
    636             // On lance le mouvement numéro runnum si la date correspond au début
     659        if (run && numobjets > 1 && runnum < numobjets)
     660        {
     661            // On lance le mouvement numéro runnum si la date et l'heure correspondent au début
    637662            // de son exécution et que ce mouvement n'a pas été encore réalisé
    638663
    639             if (JJ >= objets[runnum].JJ && !objets[runnum].exec)
     664            if ( JJ >= objets[runnum].JJ && !objets[runnum].exec )
    640665            {
    641                 // petit message pour l'utilisateur
    642 
    643                 if ( runnum == 1 ) Affiche("Début de l'exécution du fichier de mouvements\n\n", true);
     666                // petit message pour l'utilisateur au début de l'execution du tout premier mouvement
     667
     668                if ( runnum == 1 ) AfficherLog("Début de l'exécution du fichier de mouvements\n\n", true);
    644669
    645670                os << "Suivi de l'objet n°" << runnum << endl;
    646                 Affiche(&os, true);
    647 
    648                 // on indique que le mouvement est en cours d'exécution
    649                 //ou qu'il a été déjà exécuté
    650 
    651                 objets[runnum].exec=true;
    652 
    653                 //on envoie l'ordre goto correspondant
    654 
    655                 Goto(objets[runnum].ad, objets[runnum].de, Transit, J2000);
     671
     672                AfficherLog(&os, true);
     673
     674                // on note que le mouvement est en cours d'exécution
     675                // ou qu'il a été déjà exécuté
     676
     677                objets[runnum].exec = true;
     678
     679                // on pointe l'objet correspondant
     680
     681                Goto( objets[runnum].ad, objets[runnum].de, Transit, J2000 );
    656682            }
    657683
     
    669695                if ( runnum + 1 >= numobjets )
    670696                {
    671                     Affiche("Fin de l'execution du fichier de mouvements\n\n", true);
     697                    AfficherLog("Fin de l'execution du fichier de mouvements\n\n", true);
    672698
    673699                    // on réaffiche le prompt
     
    685711                    // On sort du programme dans le cas BAOControl -r fileName
    686712
    687                     NoExit=!exitrun;
     713                    NoExit = !exitrun;
    688714                }
    689715                else
     
    702728        Dessiner();
    703729
     730        // sauvegarde les paramÚtres de correction des antennes
     731
     732        if (ModificationAlignement)
     733        {
     734            gettimeofday(&tv, NULL);
     735
     736            // on ne sauvegarde les paramÚtres des alignements que si l'horloge du systÚme vient juste
     737            // de changer de seconde. Cela evite les conflits avec le pilote indi_BAO qui cherche
     738            // quant à lui à charger ce même fichier en fin de seconde...
     739
     740            if (tv.tv_usec/1.0E6>0.0 && tv.tv_usec/1.0E6<0.1)
     741            {
     742                for (int i=0; i<numAntennes; i++) if (Antennes[i].ok == 1) Antennes[i].AlignementAntenne->EnregistrementParametresAlignement(Antennes[i].ip, "/home/" + (string)getenv("USER") + "/AlignementAntennes.cfg");
     743            }
     744        }
     745
    704746        // pause de 100 ms
    705747
     
    708750
    709751    // l'utilisateur a tapé exit... On sort du thread...
    710 
    711752
    712753    pthread_exit (0);
     
    730771**          chaine2  = "25:10:10"
    731772**
    732 ** DecompositionCommande("goto messier 1","goto", &chaine1, NULL) (avec chaine2=NULLL)
     773** DecompositionCommande("goto messier 1","goto", &chaine1, NULL) (avec chaine2=NULL)
    733774** retourne chaine1  = "messier 1"
    734775**          chaine2  = NULL
     776**
    735777***************************************************************************************/
    736778
     
    762804
    763805            // puis on prend le deuxiÚme bloc -> c'est la chaine2
     806
    764807            pos = chaine.find(" ");
    765808
     
    781824            *chaine1 = chaine;
    782825        }
    783     }
     826    } else return false;
    784827
    785828    return true;
     
    790833/**************************************************************************************
    791834** Envoie la longitude et la latitude du lieu d'observation au pilote indi_BAO
     835**
    792836***************************************************************************************/
    793837
     
    795839{
    796840    // la communication avec le pilote indi_BAO
    797     // se fait par l'envoie de fichiers xml
    798     // d'où le cÃŽté complexe des commandes
     841    // se fait par l'envoi de fichiers xml
    799842
    800843    try
     
    811854        if (!VerifReponse("name=\"GEOGRAPHIC_COORD\" state=\"Ok\""))
    812855        {
    813             Erreur("ERREUR fct EnvoyerCoordGeographiques : pas de réponse du pilote indi_BAO.\n\n");
     856            ErreurLog("ERREUR fct EnvoyerCoordGeographiques : pas de réponse du pilote indi_BAO.\n\n");
    814857
    815858            return false;
     
    821864    catch ( SocketException& e )
    822865    {
    823         Erreur("Exception was caught:" + e.description() + "\n");
     866        ErreurLog("Exception was caught:" + e.description() + "\n");
     867
    824868        return false;
    825869    }
    826870
    827     Affiche("Les coordonnées géographiques ont bien été envoyées au pilote indi_BAO\n\n", true);
     871    AfficherLog("Les coordonnées géographiques ont bien été envoyées au pilote indi_BAO\n\n", true);
    828872
    829873    return true;
     
    831875
    832876
     877/**************************************************************************************
     878** Transmet la pression et la température au pilote indi_BAO
     879**
     880***************************************************************************************/
     881
     882bool BAOcontrol::EnvoyerPressionTemperature()
     883{
     884    stringstream os;
     885
     886    try
     887    {
     888        *client_socket << "<newNumberVector device=\"BAO\" name=\"PRESSION_DATA\">";
     889        *client_socket << "<oneNumber name=\"Pression\">";
     890        os << Pression;
     891        *client_socket << os.str();
     892        os.str("");
     893        *client_socket << "</oneNumber>";
     894        *client_socket << "<oneNumber name=\"Temperature\">";
     895        os << Temperature;
     896        *client_socket << os.str();
     897        os.str("");
     898        *client_socket << "</oneNumber>";
     899        *client_socket << "</newNumberVector>";
     900
     901        if (!VerifReponse("name=\"PRESSION_DATA\" state=\"Ok\""))
     902        {
     903            ErreurLog("ERREUR fct EnvoyerPressionTemperature : pas de réponse du pilote indi_BAO.\n\n");
     904
     905            return false;
     906        }
     907    }
     908
     909    // un problÚme ?
     910
     911    catch ( SocketException& e )
     912    {
     913        ErreurLog("Exception was caught:" + e.description() + "\n");
     914
     915        return false;
     916    }
     917
     918    AfficherLog("La pression et la température ont bien été envoyées au pilote indi_BAO\n\n", true);
     919
     920    return true;
     921}
     922
     923/**************************************************************************************
     924** Envoie les paramÚtres delaitransit et delaitracking au pilote indi_BAO
     925** Ces paramÚtres définissent la durée (en sec) entre deux actualisations
     926** dans les modes tracking et transit
     927**
     928***************************************************************************************/
     929
     930bool BAOcontrol::EnvoyerDelaisModesTransitEtTracking()
     931{
     932    stringstream os;
     933
     934    try
     935    {
     936        os << delaitransit;
     937        *client_socket << "<newNumberVector device=\"BAO\" name=\"DELAY1\">";
     938        *client_socket << "<oneNumber name=\"DELAY\">";
     939        *client_socket << os.str();
     940        *client_socket << "</oneNumber>";
     941        *client_socket << "</newNumberVector>";
     942        os.str("");
     943
     944        if (!VerifReponse("name=\"DELAY1\" state=\"Ok\""))
     945        {
     946            ErreurLog("ERREUR fct EnvoyerDelaisModesTransitEtTracking : pas de réponse du pilote indi_BAO.\n\n");
     947
     948            return false;
     949        }
     950
     951        os << delaitracking;
     952        *client_socket << "<newNumberVector device=\"BAO\" name=\"DELAY2\">";
     953        *client_socket << "<oneNumber name=\"DELAY\">";
     954        *client_socket << os.str();
     955        *client_socket << "</oneNumber>";
     956        *client_socket << "</newNumberVector>";
     957        os.str("");
     958
     959        if (!VerifReponse("name=\"DELAY2\" state=\"Ok\""))
     960        {
     961            ErreurLog("ERREUR fct EnvoyerDelaisModesTransitEtTracking : pas de réponse du pilote indi_BAO.\n\n");
     962
     963            return false;
     964        }
     965    }
     966
     967    // un problÚme ?
     968
     969    catch ( SocketException& e )
     970    {
     971        ErreurLog("Exception was caught:" + e.description() + "\n");
     972
     973        return false;
     974    }
     975
     976    return true;
     977}
     978
     979
     980
     981/**************************************************************************************
     982** Envoie les paramÚtres delaitransit et delaitracking au pilote indi_BAO
     983** Ces paramÚtres définissent la durée (en sec) entre deux actualisations
     984** dans les modes tracking et transit
     985**
     986***************************************************************************************/
     987
     988bool BAOcontrol::EnvoyerMethodeAlignement()
     989{
     990    stringstream os;
     991
     992    try
     993    {
     994        *client_socket << "<newSwitchVector device=\"BAO\" name=\"ALIGNMENT_SET\">";
     995        *client_socket << "<oneSwitch name=\"SIMPLE\">";
     996        (MethodeAlignement == SIMPLE) ? *client_socket << "On" : *client_socket << "Off";
     997        *client_socket << "</oneSwitch>";
     998        *client_socket << "<oneSwitch name=\"AFFINE\">";
     999        (MethodeAlignement == AFFINE) ? *client_socket << "On" : *client_socket << "Off";
     1000        *client_socket << "</oneSwitch>";
     1001        *client_socket << "<oneSwitch name=\"TAKI\">";
     1002        (MethodeAlignement == TAKI) ? *client_socket << "On" : *client_socket << "Off";
     1003        *client_socket << "</oneSwitch>";
     1004        *client_socket << "</newSwitchVector>";
     1005
     1006        if (!VerifReponse("name=\"ALIGNMENT_SET\" state=\"Ok\""))
     1007        {
     1008            ErreurLog("ERREUR fct EnvoyerMethodeAlignement : pas de réponse du pilote indi_BAO.\n\n");
     1009
     1010            return false;
     1011        }
     1012    }
     1013
     1014    // un problÚme ?
     1015
     1016    catch ( SocketException& e )
     1017    {
     1018        ErreurLog("Exception was caught:" + e.description() + "\n");
     1019
     1020        return false;
     1021    }
     1022
     1023    return true;
     1024}
     1025
    8331026
    8341027/**************************************************************************************
    8351028** Place les antennes en position de repos
     1029**
    8361030***************************************************************************************/
    8371031
     
    8481042        if (!VerifReponse("PARK OK"))
    8491043        {
    850             Erreur("La commande PARK a échoué.\n\n");;
     1044            ErreurLog("La commande PARK a échoué.\n\n");;
    8511045
    8521046            return false;
     
    8551049    catch ( SocketException& e)
    8561050    {
    857         Erreur("Exception was caught:" + e.description() + "\n");
     1051        ErreurLog("Exception was caught:" + e.description() + "\n");
     1052
    8581053        return false;
    8591054    }
    8601055
    861     Affiche("Le pilote indi_BAO a bien reçu la commande PARK.\n\n", true);
     1056    AfficherLog("Le pilote indi_BAO a bien reçu la commande PARK.\n\n", true);
    8621057
    8631058    return true;
     
    8681063/**************************************************************************************
    8691064** Annule le mouvement en cours
     1065**
    8701066***************************************************************************************/
    8711067
     
    8821078        if (!VerifReponse("ABORT OK"))
    8831079        {
    884             Erreur("L'annulation a échoué.\n\n");
     1080            ErreurLog("L'annulation a échoué.\n\n");
    8851081
    8861082            return false;
     
    8891085    catch ( SocketException& e)
    8901086    {
    891         Erreur("Exception was caught:" + e.description() + "\n");
     1087        ErreurLog("Exception was caught:" + e.description() + "\n");
     1088
    8921089        return false;
    8931090    }
    8941091
    895     Affiche("Le pilote indi_BAO a bien reçu la commande ABORT.\n\n", true);
     1092    AfficherLog("Le pilote indi_BAO a bien reçu la commande ABORT.\n\n", true);
    8961093
    8971094    return true;
     
    9031100** Diriger l'antenne vers les coordonnées ar et dec et suivre l'objet
    9041101** en activant le mode transit ou tracking.
     1102**
    9051103** si J2000 == true, cela signifie que les coordonnées ar et dec sont données dans le
    9061104** le systÚme de coordonnées J2000 (écliptique et équinoxe du 1 janvier 2000 à 0 h TU)
    907 ** Des calculs supplémentaires (précession, nutation, abérration) sont alors nécessaires
     1105** Des calculs supplémentaires (précession, nutation, aberration) sont alors réalisés
     1106** pour ramener les coordonnées ad et dec à l'écliptique et l'équinoxe de la date de
     1107** l'observation.
     1108**
    9081109***************************************************************************************/
    9091110
    9101111bool BAOcontrol::Goto(string ar, string dec, bool Transit, bool J2000)
    9111112{
     1113    double arf, decf;
     1114    double azi, hau;
    9121115    float  ar1, ar2, ar3;
    9131116    float  dec1, dec2, dec3;
    914     double arf, decf;
    915     double azi, hau;
    916 
    917 
    918      /*
    919      //Pour les tests
    920      ar="05:39:14.8";
    921      dec="23:19:24.1";
    922      printf("JJ=%10.10f\n", GetJJ());
    923      J2000=true;
    924      */
     1117
    9251118
    9261119    // Conversion de l'AD et de la déclinaison en radians
    9271120
    9281121    Decomposition(ar, 2, &ar1, &ar2, &ar3);
     1122
    9291123    Decomposition(dec, 0, &dec1, &dec2, &dec3);
    930    
     1124
    9311125    arf  = ( ar1  + ar2 / 60.0  + ar3 / 3600.0 ) * 15.0 * Pidiv180;
    9321126    decf = ( fabs(dec1) + dec2 / 60.0 + dec3 / 3600.0 ) * Pidiv180;
    9331127
    934     if (dec[0]=='-') decf = -decf;
     1128    if (dec[0] == '-') decf = -decf;
    9351129
    9361130    // calculs pupplémentaires pour se ramener
     
    9521146    // on en informe l'utilisateur
    9531147
    954     Affiche("Coordonnées apparentes de l'objet :\n", true);
    955 
    956     Affiche("AD=" + ar  + "   Dec=" + dec +"\n", true);
    957 
    958    
    959     /*
    960     //Tests
    961     Azimut(arf, decf, &azi, &hau);
    962 
    963     hau=RefractionAtmospherique(hau);
    964 
    965     Affiche("Coordonnées rectangulaires liées au lieu d'observation :\n", true);
    966 
    967     printf("Azimut = %s   Hauteur = %s\n", DHMS(azi*N180divPi,false).c_str(), DHMS(hau*N180divPi, false).c_str());
    968     */
     1148    AfficherLog("Coordonnées apparentes de l'objet :\n", true);
     1149
     1150    AfficherLog("AD=" + ar  + "   Dec=" + dec +"\n", true);
     1151
    9691152
    9701153    // On transmet les coordonnées au pilote BAO
     
    9861169        if (!VerifReponse("name=\"ON_COORD_SET\""))
    9871170        {
    988             Erreur("Le changement de mode TRANSIT/TRACKING a échoué.\n\n");
     1171            ErreurLog("Le changement de mode TRANSIT/TRACKING a échoué.\n\n");
    9891172
    9901173            return false;
     
    10021185        if (!VerifReponse("name=\"EQUATORIAL_EOD_COORD_REQUEST\""))
    10031186        {
    1004             Erreur("Le transfert des coordonnées de l'objet a échoué.\n\n");
     1187            ErreurLog("Le transfert des coordonnées de l'objet a échoué.\n\n");
    10051188
    10061189            return false;
     
    10091192    catch ( SocketException& e)
    10101193    {
    1011         Erreur("Exception was caught:" + e.description() + "\n");
     1194        ErreurLog("Exception was caught:" + e.description() + "\n");
     1195
    10121196        return false;
    10131197    }
    10141198
    1015     Affiche("Les nouvelles coordonnées AD=" + ar + " Dec=" + dec, true);
    1016     Affiche(" ont été envoyées au pilote indi_BAO.\n\n", true);
     1199    AfficherLog("Les nouvelles coordonnées AD=" + ar + " Dec=" + dec, true);
     1200    AfficherLog(" ont été envoyées au pilote indi_BAO.\n\n", true);
     1201
    10171202    return true;
    10181203}
     
    10411226            if (!VerifReponse("BAORadio is online"))
    10421227            {
    1043                 Erreur("La connexion a échoué.\n\n");
     1228                ErreurLog("La connexion a échoué.\n\n");
    10441229
    10451230                return false;
     
    10501235            if (!VerifReponse("BAORadio is offline"))
    10511236            {
    1052                 Erreur("La déconnexion a échoué.\n\n");
     1237                ErreurLog("La déconnexion a échoué.\n\n");
    10531238
    10541239                return false;
     
    10591244    catch ( SocketException& e )
    10601245    {
    1061         Erreur("Exception was caught:" + e.description() + "\n");
     1246        ErreurLog("Exception was caught:" + e.description() + "\n");
     1247
    10621248        return false;
    10631249    }
     
    10651251    if (connect)
    10661252    {
    1067         Affiche("La connexion a été établie avec le pilote indi_BAO.\n\n", true);
     1253        AfficherLog("La connexion a été établie avec le pilote indi_BAO.\n\n", true);
     1254
     1255        usleep(500000);
    10681256
    10691257        EnvoyerCoordGeographiques();
     1258
     1259        EnvoyerPressionTemperature();
     1260
     1261        EnvoyerDelaisModesTransitEtTracking();
     1262
     1263        EnvoyerMethodeAlignement();
    10701264    }
    10711265    else
    10721266    {
    1073         Affiche("BAOcontrol s'est bien déconnecté du pilote indi_BAO.\n\n", true);
     1267        AfficherLog("BAOcontrol s'est bien déconnecté du pilote indi_BAO.\n\n", true);
    10741268    }
    10751269
     
    10801274/**************************************************************************************
    10811275** Gestion du clavier en mode raw pour la procédure d'alignement
     1276** Cela permet de ne pas avoir à taper sur la touche 'entrée' aprÚs avoir appuyé sur
     1277** une flÚche de direction
    10821278***************************************************************************************/
    10831279
     
    10861282    static struct termios cooked;
    10871283    static int raw_actif = 0;
    1088    
     1284
    10891285    if (raw_actif == activer)
    10901286        return;
    1091    
     1287
    10921288    if (activer)
    10931289    {
    10941290        struct termios raw;
    1095        
     1291
    10961292        tcgetattr(STDIN_FILENO, &cooked);
    1097        
     1293
    10981294        raw = cooked;
    10991295        cfmakeraw(&raw);
     
    11021298    else
    11031299        tcsetattr(STDIN_FILENO, TCSANOW, &cooked);
    1104    
     1300
    11051301    raw_actif = activer;
    11061302}
     
    11091305/**************************************************************************************
    11101306** Alignement de l'antenne située à l'adresse ip
     1307**
     1308** Le principe consiste à utiliser des étoiles comme point de repÚre pour la calibration
     1309** des antennes : on compare la position calculée de chaque objet avec la position
     1310** effectivement mesurée lors de la procédure d'alignement. On en tire alors une matrice
     1311** de rotation qui doit corriger les défauts d'alignement de l'antenne (le 0 pas codeur
     1312** pas  parfaitement dirigé vers le sud et un axe de rotation az pas forcément
     1313** perpendiculaire au sol...)
    11111314***************************************************************************************/
    11121315
    1113 bool BAOcontrol::Alignement(string ip)
     1316bool BAOcontrol::AlignementAntenneIP( string ip )
    11141317{
    1115    bool test=false;
    1116    
    1117    int i;
    1118    
    1119    if (ip.rfind(".") != string::npos) ip=ip.substr(ip.rfind(".")+1);
    1120    
    1121    for (i=0; i<numAntennes; i++)
    1122    {
    1123       if (atoi(ip.c_str()) == Antennes[i].ip) { test=true; break; }
    1124    }
    1125  
    1126    if ((test) && (atoi(ip.c_str())!=0))
    1127    {
    1128          Affiche("Début de l'alignement de l'antenne.\n \
    1129          Appuyez sur les touches Z,Q,D,X pour centrer l'objet dans le viseur.\n \
    1130          (ESC pour arrêter et valider).\n\n", true);
    1131          
    1132          int c = 0;
    1133          
    1134          while (c!=27)
    1135          {
    1136            mode_raw(1);
    1137            
    1138            c = getchar();
    1139            
    1140            mode_raw(0);
    1141            
    1142            switch(c)
    1143            {
    1144              case 122 : Antennes[i].delta_ha++; Affiche("delta_ha + 1\n", true); break;
    1145              case 100 : Antennes[i].delta_az++; Affiche("delta_az + 1\n", true); break;
    1146              case 113 : Antennes[i].delta_az--; Affiche("delta_az - 1\n", true); break;
    1147              case 120 : Antennes[i].delta_ha--; Affiche("delta_ha - 1\n", true); break;
    1148            } 
    1149            
    1150            // Enregistrement des paramÚtres d'alignement des antennes
    1151    
    1152            EnregistrementParametresAlignement("/home/" + (string)getenv("USER") + "/AlignementAntennes.cfg");
    1153          }         
    1154    } 
    1155    else
    1156    {
    1157          Erreur("L'antenne située à l'adresse ip indiquée n'existe pas\n\n");
    1158          
    1159          return false;
    1160    }
    1161    
    1162    return true;
    1163 }
    1164 
    1165 
    1166 /**************************************************************************************
    1167 ** Sauvegarde des paramÚtres d'alignement des antennes
    1168 ***************************************************************************************/
    1169 
    1170 bool BAOcontrol::EnregistrementParametresAlignement(string fileName)
    1171 {
    1172     string section;
    1173     string key;
    1174     string value;
    1175     char ip[100];
     1318    static int Vitesse = 10;
     1319
     1320    bool test = false;
    11761321
    11771322    stringstream os;
    11781323
    1179     //Affiche("Enregistrement de l'alignement des antennes dans le fichier " + fileName + "\n", true);
    1180 
    1181     //Enregistrement des corrections des l'antennes
    1182 
    1183     for (int i=0; i< numAntennes; i++)
    1184     {
    1185         sprintf(ip, "%i", Antennes[i].ip);
    1186         os << "Alignement antenne ip x.x.x." << (string)ip;
    1187         section = os.str();
    1188         os.str("");
    1189         key     = "delta_az";
    1190         os << Antennes[i].delta_az;
    1191         value = os.str();
    1192         os.str("");
    1193 
    1194         writeINI((char*)section.c_str(), (char*)key.c_str(), (char*)value.c_str(), (char*)fileName.c_str());
    1195 
    1196         key     = "delta_ha";
    1197         os << Antennes[i].delta_ha;
    1198         value = os.str();
    1199         os.str("");
    1200 
    1201         writeINI((char*)section.c_str(), (char*)key.c_str(), (char*)value.c_str(), (char*)fileName.c_str());
     1324    int i, num;
     1325
     1326    char c;
     1327
     1328
     1329    ModificationAlignement=false;
     1330
     1331    // On sélectionne la bonne antenne à partir de son adresse ip (on ne prend en compte que le dernier nombre de l'adresse IP.
     1332
     1333    if ( ip.rfind(".") != string::npos ) ip = ip.substr(ip.rfind(".") + 1);
     1334
     1335    for (num=0; num<numAntennes; num++)
     1336    {
     1337        if (atoi(ip.c_str()) == Antennes[num].ip) {
     1338
     1339            test=true;
     1340
     1341            break;
     1342        }
     1343    }
     1344
     1345    // on a identifié l'antenne
     1346
     1347    if ( test && atoi(ip.c_str()) != 0 )
     1348    {
     1349        // L'alignement de l'antenne 'num' est en cours. Il ne faut pas calculer la
     1350        // matrice de correction tant que ce n'est pas fini..
     1351
     1352        AfficherLog("Début de l'alignement de l'antenne.\n\n", true);
     1353
     1354        // On charge les paramÚtres d'alignement existants s'ils existent
     1355
     1356        Antennes[num].AlignementAntenne->ChargementParametresAlignement(ip, "/home/" + (string)getenv("USER") + "/AlignementAntennes.cfg", atol(ip.c_str()), num);
     1357
     1358        // l'antenne num est en cours d'alignement
     1359
     1360        Antennes[num].AlignementAntenne->AlignementEnCours = true;
     1361
     1362        // Si on n'a pas encore effectué la premiÚre phase de l'alignement (viser la polaire) dans les méthode d'alignement AFFINE et TAKI
     1363
     1364        if ( Antennes[num].AlignementAntenne->delta_az_polar == 0 && MethodeAlignement!=SIMPLE)
     1365        {
     1366            cout << "Le radiotélescope va pointer l'étoile polaire.\n";
     1367            cout << "Agissez sur les touches Q et D pour centrer l'étoile dans le viseur...\n";
     1368            cout << "Appuyez sur A pour envoyer un ABORT à l'antenne.\n";
     1369            cout << "Puis, appuyez sur ESC pour valider...\n\n";
     1370
     1371
     1372            // On pointe l'étoile polaire
     1373
     1374            Goto("02:31:49.6", "89:15:50.9", Transit, true);
     1375
     1376            do
     1377            {
     1378                mode_raw(1);
     1379
     1380                c = getchar();
     1381
     1382                mode_raw(0);
     1383
     1384                usleep(10000);
     1385
     1386                // Gestion des touches fléchées du clavier. On modifie l'orientation de l'instrument
     1387                // sur les axes AD et Dec...
     1388
     1389                switch (c)
     1390                {
     1391                case 'd' :
     1392                    Antennes[num].AlignementAntenne->delta_az_polar++;
     1393                    ModificationAlignement=true;                       // On avertit le reste du programme du changement d'un paramÚtre
     1394                    AfficherLog("delta_az + 1\n", true);               // sur l'une des antennes -> d'où la nécessité de sauvegarder
     1395                    break;                                             // les nouveaux paramÚtres
     1396                case 'q' :
     1397                    Antennes[num].AlignementAntenne->delta_az_polar--;
     1398                    ModificationAlignement=true;
     1399                    AfficherLog("delta_az - 1\n", true);
     1400                   
     1401                    break;
     1402                case 'a' :
     1403                    Abort();
     1404                    sleep(2);
     1405
     1406                    break;
     1407
     1408               
     1409                }
     1410
     1411            } while (c!=27);
     1412        }
     1413
     1414
     1415        AfficherLog("\n\n\nListe des étoiles brillantes situées à plus de 30° au-dessus de l'horizon :\n\n", true);
     1416
     1417        UpdateTime();
     1418
     1419        // recherche les étoiles situées à une hauteur supérieure à 30 °
     1420        // (et donc accessibles à l'antenne)
     1421
     1422        for (i=1; i<numEtoiles; i++)
     1423        {
     1424            Azimut(Etoiles[i].ad, Etoiles[i].de, &Etoiles[i].az, &Etoiles[i].ha);
     1425
     1426            // calcule de la réfraction atmosphérique
     1427
     1428            Etoiles[i].ha = RefractionAtmospherique(Etoiles[i].ha);
     1429
     1430            // Sélectionner et afficher les étoiles > 30°
     1431
     1432            if ( Etoiles[i].selectionnee = ((Etoiles[i].ha > (HAUTMIN + 5.0) * Pidiv180) && (Etoiles[i].mag < MAGNITUDEMAXETOILESCALIBRATION)) )
     1433            {
     1434                os.width(20);
     1435                os << Etoiles[i].nom;
     1436                os << "\t(" << Etoiles[i].cons << ")\taz=" << Etoiles[i].az * N180divPi << "°\tha=";
     1437                os << Etoiles[i].ha * N180divPi << "°\tmagnitude=" << Etoiles[i].mag << "\n";
     1438
     1439                AfficherLog(&os, true);
     1440            }
     1441
     1442            if (Etoiles[i].selectionnee)
     1443            {
     1444                for (int j=1; j<=Antennes[num].AlignementAntenne->nbrcorrections; j++)
     1445                {
     1446                    // Là, un point important: on ne prend pas en compte l'AD des objets dans le reste des calculs
     1447                    // Mais l'angle horaire de ces objets avec le méridien en retranchant le temps sidéral local
     1448                    // à l'ascension droite des objets. Voir les détails dans la documentation....
     1449
     1450                    double distances = DistanceAngulaireEntre2Points(
     1451                                           VerifAngle(Antennes[num].AlignementAntenne->ad[j] - Antennes[num].AlignementAntenne->tsl[j]),
     1452                                           Antennes[num].AlignementAntenne->de[j],
     1453                                           VerifAngle(Etoiles[i].ad - GetTSL()),
     1454                                           Etoiles[i].de);
     1455
     1456                    // Ici, on ne selectionne que des étoiles qui ne soont pas trop proches de positions ayant déjà servies à la calibration
     1457                    // de l'antenne et qui multiplierait les mesures sans amélioration de la précision
     1458
     1459                    if ( distances < MIN_DISTANCE_ALIGNEMENT ) Etoiles[i].selectionnee = false;
     1460                }
     1461
     1462            }
     1463        }
     1464
     1465        // Pour chaque étoile que l'on a trouvé, on demande à l'utilisateur s'il désire l'utiliser
     1466        // pour calibrer l'antenne
     1467
     1468        for (i=1; i<numEtoiles; i++)
     1469        {
     1470            if ( Etoiles[i].selectionnee )
     1471            {
     1472                AfficherLog("\nVoulez-vous pointer l'étoile " + Etoiles[i].nom + " pour aligner l'antenne ? (o/n)\n", true);
     1473                AfficherLog("(Tapez sur la touche f pour achever l'alignement de l'antenne et enregistrer les paramÚtres.)\n", true);
     1474
     1475                // activer le mode raw évite d'avoir à taper sur la touche entrée entre chaque pression
     1476                // sur le clavier
     1477
     1478                mode_raw(1);
     1479
     1480                c = getchar();
     1481
     1482                mode_raw(0);
     1483
     1484                switch (c)
     1485                {
     1486                case 'o':
     1487                {
     1488
     1489                    // On pointe l'objet
     1490
     1491                    Goto(DHMS(Etoiles[i].ad * N180divPi, true), DHMS(Etoiles[i].de * N180divPi, false), Transit, true);
     1492
     1493                    AfficherLog("Goto en cours... Veuillez attendre la fin du mouvement\n\n", true);
     1494
     1495
     1496                    // on incrémente le compteur qui est l'indice de sauvegarde des données de calibration
     1497                    // dans le tableau AlignementAntenne
     1498
     1499                    Antennes[num].AlignementAntenne->nbrcorrections++;
     1500
     1501                    // On sauvegarde les coordonnées de l'objet qui servira à la calibration de l'antenne num
     1502
     1503                    Antennes[num].AlignementAntenne->ad[Antennes[num].AlignementAntenne->nbrcorrections]  = Etoiles[i].ad;
     1504                    Antennes[num].AlignementAntenne->de[Antennes[num].AlignementAntenne->nbrcorrections]  = Etoiles[i].de;
     1505
     1506                    do
     1507                    {
     1508
     1509                        cout << "Appuyez sur les touches Z,Q,D,X pour centrer l'objet dans le viseur.\n";
     1510                        cout << "Appuyez sur S pour changer de vitesse et sur A pour envoyer un ABORT à l'antenne.\n";
     1511                        cout << "Appuyez sur G pour reprendre le suivi de l'objet aprÚs un ABORT ou un message d'erreur.\n";
     1512                        cout << "(A la fin de l'opération, appuyez sur ESC pour arrêter et valider).\n\n";
     1513
     1514                        mode_raw(1);
     1515
     1516                        c = getchar();
     1517
     1518                        mode_raw(0);
     1519
     1520                        // pause de 10ms
     1521
     1522                        usleep(10000);
     1523
     1524                        // Gestion des touches du clavier. On modifie l'orientation de l'instrument
     1525                        // sur les axes AD et Dec...
     1526                        // On sauvegarde également le temps sidéral local. Ceci nous permettra de calculer
     1527                        // l'angle horaire de l'objet pointé
     1528
     1529                        UpdateTime();
     1530
     1531                        switch (c)
     1532                        {
     1533                        case 'z' :
     1534                            Antennes[num].AlignementAntenne->tsl[Antennes[num].AlignementAntenne->nbrcorrections] = GetTSL();
     1535                            Antennes[num].AlignementAntenne->delta_de[Antennes[num].AlignementAntenne->nbrcorrections] += Vitesse;
     1536                            ModificationAlignement = true;
     1537                            AfficherLog("Dec = " + DHMS((Antennes[num].AlignementAntenne->de[Antennes[num].AlignementAntenne->nbrcorrections]
     1538                                                         + Antennes[num].AlignementAntenne->delta_de[Antennes[num].AlignementAntenne->nbrcorrections] * PasDeltaDe )
     1539                                                        * N180divPi, false) + "\n\n", true);
     1540                            break;
     1541
     1542                        case 'd' :
     1543                            Antennes[num].AlignementAntenne->tsl[Antennes[num].AlignementAntenne->nbrcorrections] = GetTSL();
     1544                            Antennes[num].AlignementAntenne->delta_ad[Antennes[num].AlignementAntenne->nbrcorrections] += Vitesse;
     1545                            ModificationAlignement = true;
     1546                            AfficherLog("AD = " + DHMS((VerifAngle( Antennes[num].AlignementAntenne->ad[Antennes[num].AlignementAntenne->nbrcorrections]
     1547                                                                    + Antennes[num].AlignementAntenne->delta_ad[Antennes[num].AlignementAntenne->nbrcorrections] * PasDeltaAD ) )
     1548                                                       * N180divPi, true) + "\n\n", true);
     1549                            break;
     1550
     1551                        case 'q' :
     1552
     1553                            Antennes[num].AlignementAntenne->tsl[Antennes[num].AlignementAntenne->nbrcorrections] = GetTSL();
     1554                            Antennes[num].AlignementAntenne->delta_ad[Antennes[num].AlignementAntenne->nbrcorrections] -= Vitesse;
     1555                            ModificationAlignement = true;
     1556                            AfficherLog("AD = " + DHMS((VerifAngle( Antennes[num].AlignementAntenne->ad[Antennes[num].AlignementAntenne->nbrcorrections]
     1557                                                                    + Antennes[num].AlignementAntenne->delta_ad[Antennes[num].AlignementAntenne->nbrcorrections] * PasDeltaAD ) )
     1558                                                       * N180divPi, true) + "\n\n", true);
     1559                            break;
     1560
     1561                        case 'x' :
     1562                            Antennes[num].AlignementAntenne->tsl[Antennes[num].AlignementAntenne->nbrcorrections] = GetTSL();
     1563                            Antennes[num].AlignementAntenne->delta_de[Antennes[num].AlignementAntenne->nbrcorrections] -= Vitesse;
     1564                            ModificationAlignement = true;
     1565                            AfficherLog("Dec = " + DHMS((Antennes[num].AlignementAntenne->de[Antennes[num].AlignementAntenne->nbrcorrections]
     1566                                                         + Antennes[num].AlignementAntenne->delta_de[Antennes[num].AlignementAntenne->nbrcorrections] * PasDeltaDe )
     1567                                                        * N180divPi, false) + "\n\n", true);
     1568                            break;
     1569
     1570                        case 'a' :
     1571                            Abort();
     1572                            sleep(2);
     1573
     1574                            break;
     1575
     1576                        case 's' :
     1577                            (Vitesse == 1 ) ? Vitesse = 10 : Vitesse = 1;
     1578                            os << "Vitesse=" << Vitesse << "x\n\n";
     1579                            AfficherLog(&os,  true);
     1580
     1581                            break;
     1582
     1583                        case 'g' :
     1584                            AfficherLog("Reprise du GOTO.\n\n", true);
     1585                            Goto(DHMS(Etoiles[i].ad * N180divPi, true), DHMS(Etoiles[i].de * N180divPi, false), Transit, true);
     1586                            sleep(2);
     1587
     1588                            break;
     1589                        }
     1590
     1591                        //touche ESC -> on sort
     1592                    } while (c!=27);
     1593                }
     1594                break;
     1595
     1596                case 'f':
     1597                {
     1598                    // on sort de la boucle en cas d'appuie sur la touche f
     1599                    i = numEtoiles;
     1600                }
     1601                break;
     1602                }
     1603            }
     1604        }
     1605
     1606        AfficherLog("\nFin de la procédure d'alignement.\n\n", true);
     1607
     1608        // On indique au reste du programme que la calibration sur l'antenne num est terminée
     1609
     1610        Antennes[num].AlignementAntenne->AlignementEnCours = false;
     1611
     1612        ModificationAlignement=true;
     1613    }
     1614    else
     1615    {
     1616        ErreurLog("L'antenne située à l'adresse ip indiquée n'existe pas\n\n");
     1617
     1618        return false;
    12021619    }
    12031620
     
    12081625
    12091626/**************************************************************************************
    1210 ** Lecture des mouvements planifiés contenus dans le fichier fileName
    1211 ***************************************************************************************/
    1212 
    1213 bool BAOcontrol::LectureFichierMouvements(string fileName)
    1214 {
    1215     string section;
    1216     string key;
    1217     char * value   = NULL;
    1218 
    1219     stringstream os;
    1220     float a1, a2, a3, h;
    1221 
    1222     numobjets=1;
    1223 
    1224     Affiche("Lecture du fichier " + fileName +"\n\n", true);
    1225 
    1226     //Lecture de la rubrique ParamÚtres
    1227 
    1228     section = "parametres";
    1229     key     = "mode";
    1230 
    1231     if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
    1232     {
    1233         Transit = ( strstr(value, "transit") != NULL);
    1234         delete [] value;
    1235 
    1236         if (Transit) Affiche("Mode transit activé.\n", true);
    1237         else Affiche("Mode tracking activé.\n", true);
    1238     }
    1239     else
    1240     {
    1241         Erreur("Le parametre mode est incorrect.\n");
    1242         return false;
    1243     }
    1244 
    1245     key = "J2000";
    1246 
    1247     if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
    1248     {
    1249         J2000 = ( strstr(value, "on") != NULL);
    1250         delete [] value;
    1251 
    1252         if (J2000) Affiche("Mode J2000 activé.\n\n", true);
    1253         else Affiche("Mode J2000 désactivé.\n\n", true);
    1254     }
    1255     else
    1256     {
    1257         Erreur("Le parametre J2000 est incorrect.\n");
    1258         return false;
    1259     }
    1260 
    1261     // Lecture de la liste des observations
    1262 
    1263     section = "objet 1";
    1264     key     = "date";
    1265 
    1266 
    1267     while ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
    1268             && (numobjets<MAXOBJETS))
    1269     {
    1270         os << "object n°" << numobjets << endl;
    1271         Affiche(&os, true);
    1272         delete [] value;
    1273         value = NULL;
    1274 
    1275 
    1276         // Lecture de la date et de l'heure de l'observation
    1277 
    1278         key = "date";
    1279 
    1280         if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
    1281                 && (Decomposition(value, 3, &a1, &a2, &a3)))
    1282         {
    1283             Affiche("Date du début de l'observation : le " + (string)value, true);
    1284             delete [] value;
    1285             value = NULL;
    1286 
    1287             objets[numobjets].JJ = CalculJJ(a3, a2, a1, 0.0);
    1288         }
    1289         else
    1290         {
    1291             os << "La date de la rubrique [objet " << numobjets << "] est incorrecte !" << endl;
    1292             Erreur(&os);
    1293             return false;
    1294         }
    1295 
    1296         key = "heure";
    1297 
    1298         if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
    1299                 && (Decomposition(value, 2, &a1, &a2, &a3)))
    1300         {
    1301             Affiche(" à " + (string)value, true) ;
    1302             delete [] value;
    1303             value = NULL;
    1304 
    1305 
    1306             objets[numobjets].JJ += ( a1 + a2 / 60.0 + a3 / 3600.0 ) / 24.0;
    1307 
    1308             os << " TU  -> JJ=" << fixed << objets[numobjets].JJ << scientific << endl;
    1309 
    1310             Affiche(&os, true);
    1311 
    1312             for (int i=1; i<numobjets; i++)
    1313             {
    1314                 if (objets[i].JJ==objets[numobjets].JJ)
    1315                 {
    1316                     os << "Attention, les observations des objets " << i << " et ";
    1317                     os << numobjets << " sont définies à la même date !" << endl;
    1318                     Erreur(&os);
    1319                 }
    1320 
    1321                 if (objets[i].JJ+objets[i].Duree/3600/24.0>objets[numobjets].JJ)
    1322                 {
    1323                     os << "Attention, les observations des objets " << i << " et " ;
    1324                     os << numobjets << " se chevauchent !" << endl;
    1325                     Erreur(&os);
    1326                 }
    1327             }
    1328         }
    1329         else
    1330         {
    1331             os << "L'heure de la rubrique [objet " << numobjets << "] est incorrecte !" << endl;
    1332             Erreur(&os);
    1333             return false;
    1334         }
    1335 
    1336 
    1337         // Lecture de la durée de l'observation
    1338 
    1339         key = "duree";
    1340 
    1341         objets[numobjets].Duree=0.0;
    1342 
    1343         if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
    1344         {
    1345             Affiche("Durée de l'observation : " + (string)value + " secondes\n", true);
    1346             objets[numobjets].Duree=atof(value);
    1347             delete [] value;
    1348             value = NULL;
    1349         }
    1350         else
    1351         {
    1352             os << "La duree d'observation de la rubrique [objet " << numobjets << "] est incorrecte !\n";
    1353             Erreur(&os);
    1354             return false;
    1355         }
    1356 
    1357         // Lecture de l'ascension droite de l'objet
    1358 
    1359         key = "ad";
    1360 
    1361         objets[numobjets].ad = "";
    1362 
    1363         if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
    1364                 && (Decomposition(value, 2, NULL, NULL, NULL)))
    1365         {
    1366             Affiche("Ascension droite de l'objet : " + (string)value + "\n", true);
    1367             objets[numobjets].ad = value;
    1368             delete [] value;
    1369             value = NULL;
    1370         }
    1371         else
    1372         {
    1373             os << "L'ascension droite de la rubrique [objet " << numobjets << "] est incorrecte !";
    1374             os << endl;
    1375             Erreur(&os);
    1376             return false;
    1377         }
    1378 
    1379         // Lecture de la déclinaison de l'objet
    1380 
    1381         key = "de";
    1382 
    1383         objets[numobjets].de = "";
    1384 
    1385         if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
    1386                 && (Decomposition(value, 0, NULL, NULL, NULL)))
    1387         {
    1388             Affiche("Déclinaison de l'objet : " + (string)value + "\n\n", true);
    1389             objets[numobjets].de = value;
    1390             delete [] value;
    1391             value = NULL;
    1392         }
    1393         else
    1394         {
    1395             os << "La déclinaison de la rubrique [objet " << numobjets << "] est incorrecte !";
    1396             os << endl;
    1397             Erreur(&os);
    1398             return false;
    1399         }
    1400 
    1401         objets[numobjets].exec = false;
    1402 
    1403         // On passe à l'objet suivant
    1404 
    1405         numobjets++;
    1406 
    1407         os << "objet "<< numobjets;
    1408 
    1409         section = os.str();
    1410         os.str("");
    1411     }
    1412 
    1413     if (value) delete [] value;
    1414 
    1415     return true;
    1416 }
    1417 
    1418 
    1419 
    1420 /**************************************************************************************
    1421 ** Execute le fichier de mouvements
     1627** Lance l'executution d'un fichier de mouvements
     1628**
    14221629***************************************************************************************/
    14231630
     
    14281635    bool exec = LectureFichierMouvements(fichier);
    14291636
    1430     Update();
     1637    UpdateTime();
    14311638
    14321639    if ( exec && numobjets>1 )
     
    14361643        if (objets[numobjets-1].JJ + objets[numobjets-1].Duree / 3600.0 / 24.0 < GetJJ())
    14371644        {
    1438             Erreur("Le fichier contient des dates qui sont toutes périmées. Exécution annulée.\n\n");
    1439             NoExit=!exitrun;
     1645            ErreurLog("Le fichier contient des dates qui sont toutes périmées. Exécution annulée.\n\n");
     1646            NoExit = !exitrun;
     1647
    14401648            return false;
    14411649        }
    14421650        else
    14431651        {
    1444             Affiche("Execution du fichier " + fichier + " en attente...\n\n", true);
    1445             run=true;
     1652            AfficherLog("Execution du fichier " + fichier + " en attente...\n\n", true);
     1653            run = true;
    14461654        }
    14471655    }
    14481656    else
    14491657    {
    1450         Erreur("\nLe fichier " + fichier + " contient des erreurs ou n'existe pas...\n\n\n");
     1658        ErreurLog("\nLe fichier " + fichier + " contient des erreurs ou n'existe pas...\n\n\n");
    14511659        NoExit=!exitrun;
     1660
    14521661        return false;
    14531662    }
     
    14611670** Décomposition et vérification des dates, heures, AD et déclinaisons
    14621671**
    1463 ** type = 0 -> Déclinaison/latitude
     1672** type = 0 -> chaine contient une déclinaison ou une latitude
    14641673** type = 1 -> longitude
    14651674** type = 2 -> AD ou heure
    14661675** type = 3 -> date
    14671676**
    1468 ** Exemple de Decomposition("15:23:12", 2, a, b, c) retourne a=15, b=23, c=12
     1677** Exemple de Décomposition("15:23:12", 2, a, b, c) retourne a=15, b=23, c=12
    14691678** si la chaine a un format incorrect, la fct retourne false
     1679**
    14701680***************************************************************************************/
    14711681
     
    14731683{
    14741684    string car, s;
     1685
    14751686    float a, b, c;
    14761687
    14771688    // pour les heures et les coordonnées, on attend ":" comme caractÚre séparateur, sinon
    1478     // on attend d'avoir des "/" pour une date
    1479 
    1480     (type==3) ? car="/" : car=":";
     1689    // on attend d'avoir des caractÚres "/" entre chaque éléments pour une date
     1690
     1691    (type == 3) ? car="/" : car=":";
    14811692
    14821693    // Y a-t-il 2 caractÚres ':' ou '/' dans la chaine ?
    14831694    // C'est indispensable dans tous les cas
    14841695
    1485     int test=0;
     1696    int test = 0;
     1697
    14861698    for (int i=0; i<chaine.length(); i++) if (chaine[i] == car[0]) test++;
     1699
    14871700    if (test<2) return false;
    14881701
     
    14931706    a = atoi(s.c_str());
    14941707
    1495     s = chaine.substr(chaine.find(car)+1, chaine.rfind(car) - chaine.find(car) - 1);
     1708    s = chaine.substr(chaine.find(car) + 1, chaine.rfind(car) - chaine.find(car) - 1);
    14961709
    14971710    b = atoi(s.c_str());
     
    14991712    s = chaine.substr(chaine.rfind(car)+1);
    15001713
    1501     c = Arrondi(atof(s.c_str())*100.0)/100.0;
     1714    // 12.125454414 sec  -> 12.125 sec
     1715
     1716    c = Arrondi(atof(s.c_str()) * 100.0) / 100.0;
    15021717
    15031718    //vérification de la cohérence des infos contenues dans la chaine
     
    15061721    {
    15071722        // pour une déclinaison
    1508         if ((type==0) && (a>90.0  || a<-90.0)) return false;
     1723        if (( type == 0 ) && ( a>90.0  || a<-90.0 )) return false;
    15091724        // pour une AD
    1510         if ((type==1) && (a>360.0 || a<0.0  )) return false;
     1725        if (( type == 1 ) && ( a>360.0 || a<0.0   )) return false;
    15111726        // pour une heure
    1512         if ((type==2) && (a>23.0  || a<0.0  )) return false;
     1727        if (( type == 2 ) && ( a>23.0  || a<0.0   )) return false;
    15131728        // pour les minutes
    1514         if (b<0.0 || b>59.0 ) return false;
     1729        if ( b < 0.0 || b> 59.0 ) return false;
    15151730        //pour les secondes
    1516         if (c<0.0 || c>=60.0) return false;
     1731        if ( c < 0.0 || c>=60.0 ) return false;
    15171732    }
    15181733    else
    15191734    {
    15201735        //pour les jours
    1521         if (a<0.0 || a>31.0) return false;
     1736        if ( a < 0.0 || a > 31.0 ) return false;
    15221737        //pour les mois
    1523         if (b<0.0 || b>12.0) return false;
    1524     }
    1525 
    1526     if (a1!=NULL) *a1 = a;
    1527     if (a2!=NULL) *a2 = b;
    1528     if (a3!=NULL) *a3 = c;
     1738        if ( b < 0.0 || b > 12.0 ) return false;
     1739    }
     1740
     1741    if ( a1 != NULL ) *a1 = a;
     1742    if ( a2 != NULL ) *a2 = b;
     1743    if ( a3 != NULL ) *a3 = c;
    15291744
    15301745    return true;
     
    15371752** identification des commandes entrées par l'utilisateur
    15381753** puis exécution des commandes
     1754**
    15391755***************************************************************************************/
    15401756
     
    15441760    stringstream os;
    15451761
    1546     // Permet de savoir si la derniÚre saisie de l'utilisateur
     1762    // Permet de savoir si la derniÚre commande saisie par l'utilisateur
    15471763    // est une commande valide
     1764
    15481765    bool CommandeOK = false;
    15491766
     
    15531770    if ( chaine.find("goto") != string::npos )
    15541771    {
    1555         CommandeOK = true;
    15561772
    15571773        // L'utilisateur a fait suivre la commande goto de l'indication J2000
     
    15591775        if (J2000 = (chaine.find("j2000") != string::npos))
    15601776        {
    1561             Affiche("Prise en compte de la précession, de la nutation et de l'aberration...\n", true);
    1562 
    1563             // On je garde que la premiÚre partie de la chaine avant J2000
     1777            AfficherLog("Prise en compte de la précession, de la nutation et de l'aberration...\n", true);
     1778
     1779            // On ne garde que la premiÚre partie de la chaine (avant le mot "J2000")
    15641780
    15651781            chaine = chaine.substr(0, chaine.find("J2000"));
    15661782        }
    15671783
    1568         if (DecompositionCommande(chaine, "goto", &ar, &de) && Decomposition(ar, 2, NULL, NULL, NULL) && Decomposition(de, 0, NULL, NULL, NULL))
     1784        if (DecompositionCommande(chaine, "goto", &ar, &de) &&
     1785                Decomposition(ar, 2, NULL, NULL, NULL) &&
     1786                Decomposition(de, 0, NULL, NULL, NULL))
    15691787        {
    15701788            // L'utilisateur a indiqué deux coordonnées valides -> on exécute le goto
     1789
     1790            CommandeOK = true;
    15711791
    15721792            Goto(ar, de, Transit, J2000);
     
    15771797            // puis on envoie les coordonnées de l'objet au pilote indi_BAO
    15781798
     1799            CommandeOK = true;
     1800
    15791801            if ((DecompositionCommande(chaine, "goto", &objet, NULL)) && (chaine.find(":") == string::npos))
    15801802            {
    1581                 Coordonnees reponse;
    1582                
    1583                 if (objet != "sun")
    1584                 {
    1585                     reponse = ServeurNED(objet);
    1586                    
    1587                     if (reponse.ar!="" && reponse.dec!="")  Goto(reponse.ar, reponse.dec, Transit, true);
    1588                 }
    1589                 else
    1590                 {   
    1591                     printf(" lancement\n");
    1592                    
    1593                     CalculARDecSoleil(&reponse);
    1594                    
    1595                     printf("%s   %s \n", reponse.ar.c_str(), reponse.dec.c_str());
    1596                    
    1597                     Goto(reponse.ar, reponse.dec, Transit, false);
    1598                 }               
     1803                CoordonneesHoraires reponse;
     1804
     1805                if (objet != "sun")
     1806                {
     1807                    bool CestUneEtoile = false;
     1808
     1809                    for (int i=0; i<numEtoiles; i++)
     1810                    {
     1811                        if (objet == Etoiles[i].nom)
     1812                        {
     1813                            AfficherLog(Etoiles[i].nom + "\n", true);
     1814
     1815                            Goto( DHMS(Etoiles[i].ad*N180divPi, true), DHMS(Etoiles[i].de*N180divPi, false), Transit, true);
     1816
     1817                            CestUneEtoile = true;
     1818
     1819                            break;
     1820                        }
     1821                    }
     1822
     1823                    if (!CestUneEtoile)
     1824                    {
     1825                        reponse = ServeurNED(objet);
     1826
     1827                        if (reponse.ar!="" && reponse.dec!="")  Goto(reponse.ar, reponse.dec, Transit, true);
     1828                    }
     1829                }
     1830                else
     1831                {
     1832                    printf(" lancement\n");
     1833
     1834                    CalculARDecSoleil(&reponse);
     1835
     1836                    printf("%s   %s \n", reponse.ar.c_str(), reponse.dec.c_str());
     1837
     1838                    Goto(reponse.ar, reponse.dec, Transit, false);
     1839                }
    15991840            }
    16001841            else
    16011842            {
    1602                 Erreur("Erreur goto : le format de la commande est goto AD DEC\n \
    1603                     L AD doit être de la forme xx:yy:zz   (ex: 12:00:03 pour 12h 0m 3s)\n \
    1604                     La déclinaison doit être de la forme +/-xx:yy:zz (ex: -12:50:01 pour -12° 50' 01'')\n\n \
     1843                ErreurLog("Erreur goto : le format de la commande est goto AD DEC\n \
     1844                    L'AD doit être de la forme xx:yy:zz   (ex: 12:00:03 pour 12h 0m 3s)\n \
     1845                    La déclinaison doit être de la forme +/-xx:yy:zz (ex: -12:50:01.1 pour -12° 50' 01.1'')\n\n \
    16051846                    Il est egalement possible de faire suivre la commande d'un nom d'un objet\n \
    1606                     Exemple goto M 31 ou encore goto ngc145\n \
     1847                    Exemple goto M 31 ou encore goto ngc145.\n \
    16071848                    Ne pas préciser dans ce cas J2000.\n\n");
    16081849            }
     
    16221863        if (chaine.find("run") != string::npos)
    16231864        {
    1624             run=false;
    1625             runnum=1;
    1626             numobjets=1;
    1627 
    1628             Affiche("Annulation de l'exécution du fichier de mouvements.\n\n", true);
     1865            run       = false;
     1866            runnum    = 1;
     1867            numobjets = 1;
     1868
     1869            AfficherLog("Annulation de l'exécution du fichier de mouvements.\n\n", true);
    16291870
    16301871            return;
     
    16441885        else
    16451886        {
    1646             Erreur("Erreur run : la commande run doit être suivie par un nom de fichier.\n\n");
     1887            ErreurLog("Erreur run : la commande run doit être suivie par un nom de fichier.\n\n");
    16471888        }
    16481889    }
     
    16571898    }
    16581899
    1659     // Active le mode de suivi "transit"
    1660 
    1661     if (chaine.find("transit") != string::npos)
     1900
     1901
     1902    // Place les antennes en position de repos
     1903
     1904    if (chaine.find("park") != string::npos)
    16621905    {
    16631906        CommandeOK = true;
    16641907
    1665         Affiche("Mode transit activé.\n\n", true);
    1666 
    1667         Transit=true;
    1668     }
    1669 
    1670     // Active le mode de suivi "tracking"
    1671 
    1672     if (chaine.find("tracking") != string::npos)
     1908        Park();
     1909    }
     1910
     1911    // interroge un serveur de temps pour mettre l'horloge du PC à jour
     1912
     1913    if (chaine.find("updatetime") != string::npos)
    16731914    {
    16741915        CommandeOK = true;
    16751916
    1676         Affiche("Mode tracking activé.\n\n", true);
    1677 
    1678         Transit=false;
    1679     }
    1680 
    1681     // Place les antennes en position de repos
    1682 
    1683     if (chaine.find("park") != string::npos)
     1917        int rc = system("sntp -s fr.pool.ntp.org");
     1918
     1919        if (WEXITSTATUS(rc) ==-1 || WEXITSTATUS(rc) ==127)
     1920        {
     1921            ErreurLog("La commande sntp n'est pas accessible. Merci de vérifier.\n\n");
     1922        }
     1923    }
     1924
     1925    // Affiche tous les paramÚtres du programme
     1926
     1927    if (chaine.find("status") != string::npos)
    16841928    {
    16851929        CommandeOK = true;
    16861930
    1687         Park();
    1688     }
    1689 
    1690     // interroge un serveur de temps pour mettre l'horloge du PC à jour
    1691 
    1692     if (chaine.find("updatetime") != string::npos)
    1693     {
    1694         CommandeOK = true;
    1695 
    1696         int rc = system("sntp -s fr.pool.ntp.org");
    1697 
    1698         if (WEXITSTATUS(rc) ==-1 || WEXITSTATUS(rc) ==127)
    1699         {
    1700             Erreur("La commande sntp n'est pas accessible. Merci de vérifier.\n\n");
    1701         }
    1702     }
    1703 
    1704     // Affiche tous les paramÚtres du programme
    1705 
    1706     if (chaine.find("status") != string::npos)
    1707     {
    1708         CommandeOK = true;
    1709 
    1710         os << "Latitude = " << (string)LatitudeChar << "\n";
    1711         os << "Longitude = " << (string)LongitudeChar << "\n\n";
    1712         os << "Serveur Indi = " << (string)Serveur << "\n";
     1931        os << "Latitude = " << LatitudeChar << "\n";
     1932        os << "Longitude = " << LongitudeChar << "\n\n";
     1933        os << "Serveur Indi = " << Serveur << "\n";
    17131934        os << "Port du serveur Indi = " << Port << "\n\n";
    17141935        os << "Pression atmosphérique  = " << Pression << " mBar\n";
    17151936        os << "Température = " << Temperature << " °C\n\n";
    1716         Affiche(&os, true);
    1717         if (Transit) Affiche("Mode Transit activé.\n\n", true);
    1718         else Affiche ("Mode Tracking activé.\n\n", true);
     1937
     1938        os << "Antennes connectées : " << numAntennes << "\n\n";
     1939        os << "Mode ";
     1940        (Transit) ? os << "transit" : os << "tracking";
     1941        os << " activé.\n\n";
     1942        os << "Durée entre deux actualisations : ";
     1943        (Transit) ? os << delaitransit : os << delaitracking;
     1944        os << " sec(s)\n\n";
     1945        os << "Méthode d'alignement : ";
     1946        switch (MethodeAlignement)
     1947        {
     1948        case SIMPLE :
     1949            os << "simple\n";
     1950            break;
     1951        case AFFINE :
     1952            os << "affine\n";
     1953            break;
     1954        case TAKI   :
     1955            os << "taki\n";
     1956            break;
     1957        }
     1958        os << "\n\n";
     1959
     1960        AfficherLog(&os, true);
    17191961    }
    17201962
     
    17251967        string objet;
    17261968
     1969        bool CestUneEtoile = false;
     1970
    17271971        CommandeOK = true;
    17281972
    17291973        if (DecompositionCommande(chaine, "search", &objet, NULL))
    17301974        {
    1731             ServeurNED(objet);
    1732         }
    1733     }
    1734    
     1975            for (int i=0; i<numEtoiles; i++)
     1976            {
     1977                if (objet == Etoiles[i].nom)
     1978                {
     1979                    os << Etoiles[i].nom << "\n";
     1980                    os << "AD (J2000) = " << DHMS(Etoiles[i].ad*N180divPi, true) << "\n";
     1981                    os << "Dec (J2000) = " << DHMS(Etoiles[i].de*N180divPi, false) << "\n";
     1982                    AfficherLog(os.str(), true);
     1983
     1984                    CestUneEtoile = true;
     1985
     1986                    break;
     1987                }
     1988            }
     1989
     1990            if (!CestUneEtoile) ServeurNED(objet);
     1991        }
     1992    }
     1993
     1994
    17351995    // correction de l'alignement d'une antenne par rapport à l'objet visé
    17361996
     
    17432003        if (DecompositionCommande(chaine, "align", &antenne, NULL))
    17442004        {
    1745             Alignement(antenne);
     2005            AlignementAntenneIP(antenne);
    17462006        }
    17472007        else
    17482008        {
    1749             Erreur("Erreur align : la commande align doit être suivie par l'ip de l'antenne qui faut aligner.\n\n");
    1750         }
    1751     }
     2009            ErreurLog("Erreur align : la commande align doit être suivie par l'ip de l'antenne qui faut aligner.\n\n");
     2010        }
     2011    }
     2012
     2013
     2014    // Réinitialisation de l'alignement d'une antenne
     2015
     2016    if (chaine.find("reset")!=string::npos)
     2017    {
     2018        string ip;
     2019
     2020        CommandeOK = true;
     2021
     2022        int num;
     2023
     2024        if (DecompositionCommande(chaine, "reset", &ip, NULL))
     2025        {
     2026            bool test = false;
     2027
     2028            // On sélectionne la bonne antenne (à partir de son adresse ip).
     2029
     2030            if (ip.rfind(".") != string::npos) ip = ip.substr(ip.rfind(".")+1);
     2031
     2032            for (num=0; num<numAntennes; num++)
     2033            {
     2034                if (atoi(ip.c_str()) == Antennes[num].ip) {
     2035
     2036                    test = true;
     2037
     2038                    break;
     2039                }
     2040            }
     2041
     2042            // on a identifié l'antenne
     2043
     2044            if ((test) && (atoi(ip.c_str()) != 0))
     2045            {
     2046                // initialisation des paramÚtres de l'alignement de l'antenne numAntennes
     2047
     2048                Antennes[num].AlignementAntenne->InitAlignement();
     2049
     2050                ModificationAlignement = true;
     2051
     2052                AfficherLog("Les paramÚtres d'alignement de l'antenne " + ip +" ont été réinitialisés.\n\n", true);
     2053            }
     2054            else
     2055            {
     2056                AfficherLog("L'antenne indiquée ne semble pas connectée.\n\n", true);
     2057            }
     2058        }
     2059        else
     2060        {
     2061            ErreurLog("Erreur reset : la commande reset doit être suivie par l'ip de l'antenne qu'il faut aligner.\n\n");
     2062        }
     2063    }
     2064
     2065
     2066    // Commande set
     2067
     2068    if (chaine.find("set") != string::npos)
     2069    {
     2070        string commande, commande2, commande3;
     2071
     2072        // est-ce que la commande commande par set ! -> si oui, la variable commande contient alors le reste de
     2073        // la phrase saisie par l'utilisateur
     2074
     2075        if (DecompositionCommande(chaine, "set", &commande, NULL))
     2076        {
     2077            // A-t-on set transit xxxx ?
     2078
     2079            if (DecompositionCommande(commande, "transit", &commande2, &commande3))
     2080            {
     2081                //at-ton set transit delay xxx ?
     2082
     2083                if (commande2 == "delay")
     2084                {
     2085                    if (atoi(commande3.c_str()) > 0)
     2086                    {
     2087                        CommandeOK = true;
     2088
     2089                        delaitransit = atoi(commande3.c_str());
     2090
     2091                        EnvoyerDelaisModesTransitEtTracking();
     2092
     2093                        AfficherLog("Delai entre deux actualisations en mode transit : " + commande3 + "\n\n" , true);
     2094                    }
     2095                    else
     2096                    {
     2097                        AfficherLog("Le nombre qui suit le mot clé delay doit être entier et > 0  \n\n" , true);
     2098                    }
     2099                }
     2100
     2101                // Active le mode de suivi "transit"
     2102
     2103                if (commande2 == "on")
     2104                {
     2105                    CommandeOK = true;
     2106
     2107                    AfficherLog("Mode transit activé.\n\n", true);
     2108
     2109                    Transit = true;
     2110                }
     2111            }
     2112
     2113            // a-t-on set tracking xxxx ?
     2114
     2115            if (DecompositionCommande(commande, "tracking", &commande2,  &commande3))
     2116            {
     2117                // a-ton set tracking delay xxx ?
     2118
     2119                if (commande2 == "delay")
     2120                {
     2121                    if (atoi(commande3.c_str())>0)
     2122                    {
     2123                        CommandeOK = true;
     2124
     2125                        delaitracking = atoi(commande3.c_str());
     2126
     2127                        EnvoyerDelaisModesTransitEtTracking();
     2128
     2129                        AfficherLog("Delai entre deux actualisations en mode tracking : " + commande3 + "\n\n" , true);
     2130                    }
     2131                    else
     2132                    {
     2133                        AfficherLog("Le nombre qui suit le mot clé delay doit être entier et > 0  \n\n" , true);
     2134                    }
     2135                }
     2136
     2137                // Active le mode de suivi "transit"
     2138
     2139                if (commande2 == "on")
     2140                {
     2141                    CommandeOK = true;
     2142
     2143                    AfficherLog("Mode tracking activé.\n\n", true);
     2144
     2145                    Transit = false;
     2146                }
     2147            }
     2148
     2149            // A-t-on set alignment ?
     2150
     2151            if (DecompositionCommande(commande, "alignment", &commande2,  &commande3))
     2152            {
     2153
     2154                // A-ton set alignment method xxx ?
     2155
     2156                if (commande2 == "method")
     2157                {
     2158                    MethodeAlignement = NONE;
     2159
     2160                    if (commande3 == "simple") MethodeAlignement = SIMPLE;
     2161                    if (commande3 == "affine") MethodeAlignement = AFFINE;
     2162                    if (commande3 == "taki")   MethodeAlignement = TAKI;
     2163
     2164                    if (MethodeAlignement == NONE )
     2165                    {
     2166                        MethodeAlignement = SIMPLE;
     2167
     2168                        AfficherLog("Erreur: la syntaxe doit être 'set alignment method x' avec x = simple/affine/taki)\n\n" , true);
     2169                    }
     2170                    else
     2171                    {
     2172                        CommandeOK = true;
     2173
     2174                        EnvoyerMethodeAlignement();
     2175
     2176                        switch (MethodeAlignement)
     2177                        {
     2178                        case  SIMPLE :
     2179                            AfficherLog("Activation de la méthode d'alignement simple\n\n", true);
     2180                            break;
     2181                        case  AFFINE :
     2182                            AfficherLog("Activation de la méthode d'alignement affine\n\n", true);
     2183                            break;
     2184                        case  TAKI :
     2185                            AfficherLog("Activation de la méthode d'alignement taki\n\n", true);
     2186                            break;
     2187                        }
     2188                    }
     2189                }
     2190                else
     2191                {
     2192                    AfficherLog("Erreur: la syntaxe doit être 'set alignment method x' avec x = simple/affine/taki)\n\n" , true);
     2193                }
     2194            }
     2195        }
     2196    }
     2197
     2198
     2199
     2200
     2201
    17522202
    17532203    // Aide du programme
     
    17592209        cout << endl;
    17602210
    1761         cout << "connect :           se connecte au pilote indi_BAO." << endl;
    1762         cout << "disconnect :        se déconnecte du pilote indi_BAO." << endl;
    1763         cout << "goto AD Dec :       pointe l'objet situé aux coordonnées apparentes AD Dec." << endl;
    1764         cout << "                    AD doit être au format xx:yy:zz et dec au format +/-xx:yy:zz" << endl;
    1765         cout << "                    exemple goto 12:10:05 -05:10:11 permettra de pointer l'objet" << endl;
    1766         cout << "                    situé aux coordonnées AD=12h10m5s et dec=-5°10'11''" << endl;
    1767         cout << "goto AD Dec J2000 : pointe l'objet situé aux coordonnées AD Dec dans le repÚre J2000." << endl;
    1768         cout << "                    Avant de pointer l'objet, le programme calcule la précession, la nutation et l'aberration" << endl;
    1769         cout << "                    pour ramener les coordonnées à l'écliptique et à l'équinoxe de l'observation." << endl;
    1770         cout << "goto nom_objet :    interroge la base NED pour trouver les coordonnées de l'objet puis le pointe." << endl;
    1771         cout << "                    exemples: goto m 31, goto messier 1, goto ngc 175, goto ic 434 etc..." << endl;
    1772         cout << "                    Dans ce mode, les coordonnées sont automatiquement rapportées" << endl;
    1773         cout << "                    à l'écliptique et à l'équinoxe de l'observation." << endl;
    1774         cout << "                    Aussi, merci de ne pas faire suivre les coordonnées de l'indication J2000."<< endl;
    1775         cout << "                    Goto sun permet de suivre le soleil." << endl;
    1776         cout << "search nom_objet :  interroge le serveur NED sur internet et retourne les coordonnées de l'objet." << endl;
    1777         cout << "align ip :          lance la procédure d'alignement de l'antenne d'adresse ip." << endl;
    1778         cout << "transit :           active le mode de suivi transit." << endl;
    1779         cout << "tracking :          active le mode de suivi tracking." << endl;
    1780         cout << "status :            liste les paramÚtres du programme." << endl;
    1781         cout << "run filename :      exécute le fichier de mouvements filename." << endl;
    1782         cout << "abort run :         annule l'exécution du fichier de mouvements." << endl;
    1783         cout << "abort :             annule le mouvement en cours." << endl;
    1784         cout << "park :              place les antennes en position de repos." << endl;
    1785         cout << "updatetime :        synchronise l'horloge du PC avec un serveur de temps." << endl;
    1786         cout << "exit :              sortir de BAOControl." << endl;
     2211        cout << "connect :                Se connecte au pilote indi_BAO." << endl;
     2212        cout << "disconnect :             Se déconnecte du pilote indi_BAO." << endl;
     2213        cout << "goto AD Dec :            Pointe l'objet situé aux coordonnées apparentes AD Dec." << endl;
     2214        cout << "                         AD doit être au format xx:yy:zz et dec au format +/-xx:yy:zz" << endl;
     2215        cout << "                         exemple goto 12:10:05 -05:10:11 permettra de pointer l'objet" << endl;
     2216        cout << "                         situé aux coordonnées AD=12h10m5s et dec=-5°10'11''" << endl;
     2217        cout << "goto AD Dec J2000 :      Pointe l'objet situé aux coordonnées AD Dec dans le repÚre J2000." << endl;
     2218        cout << "                         Avant de pointer l'objet, le programme calcule la précession, la nutation et l'aberration" << endl;
     2219        cout << "                         pour ramener les coordonnées à l'écliptique et à l'équinoxe de l'observation." << endl;
     2220        cout << "goto nom_objet :         Interroge la base NED pour trouver les coordonnées de l'objet puis le pointe." << endl;
     2221        cout << "                         exemples: goto m 31, goto messier 1, goto ngc 175, goto ic 434 etc..." << endl;
     2222        cout << "                         Dans ce mode, les coordonnées sont automatiquement rapportées" << endl;
     2223        cout << "                         Ã  l'écliptique et à l'équinoxe de l'observation." << endl;
     2224        cout << "                         Aussi, merci de ne pas faire suivre les coordonnées de l'indication J2000."<< endl;
     2225        cout << "                         Goto sun permet de suivre le soleil." << endl;
     2226        cout << "search nom_objet :       Interroge le serveur NED sur internet et retourne les coordonnées de l'objet." << endl;
     2227        cout << "align ip :               Lance la procédure d'alignement de l'antenne d'adresse ip." << endl;
     2228        cout << "reset ip :               Réinitialise les paramÚtres d'alignement de l'antenne d'adresse ip." << endl;
     2229        cout << "set transit on :         Active le mode de suivi transit." << endl;
     2230        cout << "set transit delay x :    Fixe la durée entre deux actualisations à x seconde(s) dans le mode transit" << endl;
     2231        cout << "set tracking on :        Active le mode de suivi tracking." << endl;
     2232        cout << "set tracking delay x :   Fixe la durée entre deux actualisations à x seconde(s) dans le mode tracking" << endl;
     2233        cout << "set alignment method x : Aligne les antennes en utilisant la méthode x (simple/affine/taki)" << endl;
     2234        cout << "status :                 Liste les paramÚtres du programme." << endl;
     2235        cout << "run filename :           Exécute le fichier de mouvements filename." << endl;
     2236        cout << "abort run :              Annule l'exécution du fichier de mouvements." << endl;
     2237        cout << "abort :                  Annule le mouvement en cours." << endl;
     2238        cout << "park :                   Place les antennes en position de repos." << endl;
     2239        cout << "updatetime :             Synchronise l'horloge du PC avec un serveur de temps." << endl;
     2240        cout << "exit :                   Sortir de BAOControl." << endl;
    17872241
    17882242        cout << endl;
     
    17912245    // Bye !
    17922246
    1793     if (chaine.find("exit")!=string::npos)
     2247    if (chaine.find("exit") != string::npos)
    17942248    {
    17952249        CommandeOK = true;
    17962250
    1797         Abort();
     2251        if ( numAntennes > 0 ) Abort();
     2252
     2253        usleep(500000);
    17982254
    17992255        Connect(false);
     
    18042260    // La commande n'a pas été identifiée !
    18052261
    1806     if (!CommandeOK) Erreur("Commande inconnue... Tapez help pour obtenir la liste des commandes disponibles.\n\n");
     2262    if (!CommandeOK) ErreurLog("Commande inconnue... Tapez help pour obtenir la liste des commandes disponibles.\n\n");
    18072263}
     2264
    18082265
    18092266
    18102267/**************************************************************************************
    18112268** Interroge le serveur NED sur internet et retourne les coordonnées dans le repÚre J2000
    1812 ** Si pas de réponse, alors message d'erreur et les coordonnées sont égales à AR="" dec=""
     2269** Si pas de réponse, alors message d'erreur et les coordonnées retournées sont
     2270** égales à AD="" dec=""
     2271**
    18132272***************************************************************************************/
    18142273
    1815 Coordonnees BAOcontrol::ServeurNED(string objet)
     2274CoordonneesHoraires BAOcontrol::ServeurNED(string objet)
    18162275{
    1817     Coordonnees reponse;
     2276    CoordonneesHoraires reponse;
    18182277    stringstream send;
    18192278
     
    18332292    // Effacer le fichier result s'il existe dans le répertoire du programme
    18342293
    1835     if ((pFile = fopen ("result", "r")) != NULL )
     2294    if ((pFile = fopen ("result_recherche_bao", "r")) != NULL )
    18362295    {
    18372296        fclose (pFile);
    1838         rc = system( "rm result");
     2297        rc = system( "rm -rf result_recherche_bao");
    18392298    }
    18402299
     
    18422301    // On sauvegarde le résultat dans le fichier result
    18432302
    1844     send << "curl >> result \"http://ned.ipac.caltech.edu/cgi-bin/nph-objsearch?objname=";
     2303    send << "curl >> result_recherche_bao \"http://ned.ipac.caltech.edu/cgi-bin/nph-objsearch?objname=";
    18452304    send << objet;
    18462305    send << "&extend=no&hconst=73&omegam=0.27&omegav=0.73&corr_z=1&out_csys=Equatorial&out_equinox=J2000.0";
    18472306    send << "&obj_sort=RA+or+Longitude&of=ascii_bar&zv_breaker=30000.0&list_limit=5&img_stamp=NO\"";
    18482307
    1849     Affiche("Envoi de la requête au serveur NED...\n", true);
     2308    AfficherLog("Envoi de la requête au serveur NED...\n", true);
    18502309
    18512310    // on lance la requête
     
    18572316    if (WEXITSTATUS(rc) ==-1 || WEXITSTATUS(rc) ==127)
    18582317    {
    1859         Erreur("La commande curl n'est pas accessible. Merci de vérifier.\n\n");
     2318        ErreurLog("La commande curl n'est pas accessible. Merci de vérifier.\n\n");
    18602319    }
    18612320    else
    18622321    {
    1863         // On a obtenu quelque chose
     2322        // On a reçu quelque chose
    18642323
    18652324        int nbRead = 0;
     
    18762335        // On ouvre le fichier result
    18772336
    1878         pFile = fopen ("result", "r");
     2337        pFile = fopen ("result_recherche_bao", "r");
    18792338
    18802339        if (pFile)
     
    18892348                    // Le fichier contient une indication d'erreur -> pas de réponse exploitable
    18902349
    1891                     Affiche("\nLe serveur NED n'a pas trouvé de réponse à votre demande...\n", true);
     2350                    AfficherLog("\nLe serveur NED n'a pas trouvé de réponse à votre demande...\n", true);
    18922351                }
    18932352                else
     
    18952354                    // on analyse la réponse
    18962355
    1897                     Affiche("\nRéponse du serveur :\n", true);
     2356                    AfficherLog("\nRéponse du serveur :\n", true);
    18982357
    18992358                    do
     
    19052364                        {
    19062365                            string chaine = (string)pBuf;
    1907                             string chaine2;
    19082366
    19092367                            chaine=chaine.substr(chaine.find('|')+1);
     
    19112369                            // affiche le nom de l'objet dans le serveur NED
    19122370
    1913                             Affiche(chaine.substr(0, chaine.find('|')) + "\n", true);
     2371                            AfficherLog(chaine.substr(0, chaine.find('|')) + "\n", true);
    19142372
    19152373                            chaine = chaine.substr(chaine.find('|') + 1);
    19162374
     2375                            string chaine2 = chaine.substr(0, chaine.find('|'));
     2376
     2377                            double ar = atof(chaine2.c_str());
     2378
     2379                            // affiche l'ascension droite
     2380
     2381                            AfficherLog("AD (J2000) = " + DHMS(ar, true) + "\n", true);
     2382
     2383                            reponse.ar = DHMS(ar, true);
     2384
     2385                            chaine=chaine.substr(chaine.find('|')+1);
     2386
    19172387                            chaine2 = chaine.substr(0, chaine.find('|'));
    19182388
    1919                             double ar = atof(chaine2.c_str());
    1920 
    1921                             // affiche l'ascension droite
    1922 
    1923                             Affiche("AD (J2000) = " + DHMS(ar, true) + "\n", true);
    1924 
    1925                             reponse.ar = DHMS(ar, true);
    1926 
    1927                             chaine=chaine.substr(chaine.find('|')+1);
    1928 
    1929                             chaine2 = chaine.substr(0, chaine.find('|'));
    1930 
    19312389                            double dec = atof(chaine2.c_str());
    19322390
    19332391                            // on affiche la déclinaison
    19342392
    1935                             Affiche("Dec (J2000) = " + DHMS(dec, false)+"\n", true);
     2393                            AfficherLog("Dec (J2000) = " + DHMS(dec, false)+"\n", true);
    19362394
    19372395                            reponse.dec = DHMS(dec, false);
     
    19452403            else
    19462404            {
    1947                 Erreur("\nLa connexion semble impossible avec le serveur NED !\n\n");
     2405                ErreurLog("\nLa connexion semble impossible avec le serveur NED !\n\n");
    19482406            }
    19492407
     
    19522410        else
    19532411        {
    1954             Erreur("\nLa connexion semble impossible avec le serveur NED !\n\n");
     2412            ErreurLog("\nLa connexion semble impossible avec le serveur NED !\n\n");
    19552413        }
    19562414
    19572415        delete [] pBuf;
    19582416
    1959         Affiche("\n", true);
     2417        AfficherLog("\n", true);
    19602418    }
    19612419
     
    19732431{
    19742432    int nbchar = 0;
     2433
    19752434    char c;
    19762435
     
    20012460/**************************************************************************************
    20022461** chargement des paramÚtres contenus dans le fichier params
     2462**
    20032463***************************************************************************************/
    20042464
     
    20112471
    20122472
    2013 
    2014     Affiche("Lecture du fichier de configuration 'params' :\n\n", true);
     2473    // Si le fichier n'existe pas -> on sort
     2474
     2475    if (!is_readable(fileName)) return false;
     2476
     2477
     2478    AfficherLog("Lecture du fichier de configuration 'params' :\n\n", true);
    20152479
    20162480
     
    20262490    {
    20272491        LatitudeChar = (string)value;
    2028         delete [] value;
    2029         Affiche("latitude = " + LatitudeChar +"\n", true);
     2492        SAFEDELETE_TAB(value);
     2493        AfficherLog("latitude = " + LatitudeChar +"\n", true);
    20302494    }
    20312495    else
    20322496    {
    2033         Erreur("La latitude est incorrecte !\n");
     2497        ErreurLog("La latitude est incorrecte !\n");
     2498
    20342499        return false;
    20352500    }
     
    20422507    {
    20432508        LongitudeChar = (string)value;
    2044         delete [] value;
    2045         Affiche("longitude = " + LongitudeChar +"\n\n", true);
     2509        SAFEDELETE_TAB(value);
     2510        AfficherLog("longitude = " + LongitudeChar +"\n\n", true);
    20462511    }
    20472512    else
    20482513    {
    2049         Erreur("La longitude est incorrecte !\n");
     2514        ErreurLog("La longitude est incorrecte !\n");
     2515
    20502516        return false;
    20512517    }
     
    20622528    {
    20632529        Serveur = (string)value;
    2064         delete [] value;
    2065         Affiche("serveur = " + Serveur +"\n", true);
     2530        SAFEDELETE_TAB(value);
     2531        AfficherLog("serveur = " + Serveur +"\n", true);
    20662532    }
    20672533    else
    20682534    {
    2069         Erreur("Nom du serveur invalide !\n");
     2535        ErreurLog("Nom du serveur invalide !\n");
     2536
    20702537        return false;
    20712538    }
     
    20772544    {
    20782545        Port = (string)value;
    2079         delete [] value;
    2080         Affiche("port = " + Port +"\n\n", true);
     2546        SAFEDELETE_TAB(value);
     2547        AfficherLog("port = " + Port +"\n\n", true);
    20812548    }
    20822549    else
    20832550    {
    2084         Erreur("Numéro de port incorrect !\n");
     2551        ErreurLog("Numéro de port incorrect !\n");
     2552
    20852553        return false;
    20862554    }
     
    20972565    {
    20982566        Pression = atof(value);
    2099         delete [] value;
     2567        SAFEDELETE_TAB(value);
    21002568        os << "pression = " << Pression << endl;
    2101         Affiche(&os, true);
     2569        AfficherLog(&os, true);
    21022570    }
    21032571    else
    21042572    {
    2105         os << "La pression atmosph&rique est incorrecte !" << endl;
    2106         Erreur(&os);
     2573        os << "La pression atmosphérique est incorrecte !" << endl;
     2574        ErreurLog(&os);
     2575
    21072576        return false;
    21082577    }
     
    21122581    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
    21132582    {
    2114         Temperature=atof(value);
    2115         delete [] value;
     2583        Temperature = atof(value);
     2584        SAFEDELETE_TAB(value);
    21162585        os << "température = " << Temperature << endl << endl;
    2117         Affiche(&os, true);
     2586        AfficherLog(&os, true);
    21182587    }
    21192588    else
    21202589    {
    2121         Erreur("La température est incorrecte !\n");
     2590        ErreurLog("La température est incorrecte !\n");
     2591
    21222592        return false;
    21232593    }
     
    21342604    {
    21352605        Transit = (strstr(value, "transit") != NULL);
    2136         Affiche("mode suivi = " + (string)value + "\n", true);
    2137         delete [] value;
     2606        AfficherLog("mode suivi = " + (string)value + "\n", true);
     2607        SAFEDELETE_TAB(value);
    21382608    }
    21392609    else
    21402610    {
    2141         Erreur("Le paramÚtre mode est incorrect !\n");
     2611        ErreurLog("Le paramÚtre mode est incorrect !\n");
     2612
    21422613        return false;
    21432614    }
     
    21492620    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
    21502621    {
    2151         delaitransit=atoi(value);
    2152         delete [] value;
     2622        delaitransit = atoi(value);
     2623        SAFEDELETE_TAB(value);
    21532624        os << "delai transit = " << delaitransit << " sec" << endl;
    2154         Affiche(&os, true);
     2625        AfficherLog(&os, true);
    21552626    }
    21562627    else
    21572628    {
    2158         Erreur("Le paramÚtre delai_transit est incorrect !\n");
     2629        ErreurLog("Le paramÚtre delai_transit est incorrect !\n");
     2630
    21592631        return false;
    21602632    }
     
    21652637    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
    21662638    {
    2167         delaitracking=atoi(value);
    2168         delete [] value;
     2639        delaitracking = atoi(value);
     2640        SAFEDELETE_TAB(value);
    21692641        os << "delai tracking = " << delaitracking << " sec" << endl << endl;
    2170         Affiche(&os, true);
     2642        AfficherLog(&os, true);
    21712643    }
    21722644    else
    21732645    {
    2174         Erreur("Le paramÚtre delai_tracking est incorrect !\n");
     2646        ErreurLog("Le paramÚtre delai_tracking est incorrect !\n");
     2647
    21752648        return false;
    21762649    }
     
    21872660    {
    21882661        ChoixCouleurs=atoi(value);
    2189         delete [] value;
     2662        SAFEDELETE_TAB(value);
    21902663    }
    21912664    else
    21922665    {
    21932666        /*os << "Le paramÚtre couleurs est incorrect !" << endl;
    2194         Erreur(os.str());
     2667        ErreurLog(os.str());
    21952668        return false;*/
    21962669    }
     
    21982671    return true;
    21992672}
     2673
     2674
     2675
     2676
     2677
     2678
     2679/**************************************************************************************
     2680** Lecture des mouvements planifiés contenus dans le fichier fileName
     2681** Ces fichiers de mouvement planifiés permettent des observations automatisées
     2682** d'une liste d'objets (ou zone du ciel) pour lesquels on passe de l'un à l'autre
     2683** en fonction de l'heure
     2684**
     2685***************************************************************************************/
     2686
     2687bool BAOcontrol::LectureFichierMouvements(string fileName)
     2688{
     2689    string section;
     2690    string key;
     2691    char * value   = NULL;
     2692
     2693    stringstream os;
     2694    float a1, a2, a3, h;
     2695
     2696
     2697    // Si le fichier n'existe pas -> on sort
     2698
     2699    if (!is_readable( fileName )) return false;
     2700
     2701    AfficherLog("Lecture du fichier " + fileName +"\n\n", true);
     2702
     2703    // initialisation du compteur nombre objets
     2704
     2705    numobjets = 1;
     2706
     2707    //Lecture de la rubrique ParamÚtres
     2708
     2709    section = "parametres";
     2710
     2711    // Mode transit ou tracking ?
     2712
     2713    key     = "mode";
     2714
     2715    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
     2716    {
     2717        Transit = ( strstr(value, "transit") != NULL);
     2718        // il faut détruire les tableaux de caratÚres qui sont crées
     2719        // dans la fonction ReadINI
     2720        SAFEDELETE_TAB(value);
     2721
     2722        if (Transit) AfficherLog("Mode transit activé.\n", true);
     2723        else AfficherLog("Mode tracking activé.\n", true);
     2724    }
     2725    else
     2726    {
     2727        ErreurLog("Le parametre mode est incorrect.\n");
     2728
     2729        return false;
     2730    }
     2731
     2732    // Les coordonnées sont-elles dans le systÚme de coordonnées J2000 ?
     2733
     2734    key = "J2000";
     2735
     2736    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
     2737    {
     2738        J2000 = ( strstr(value, "on") != NULL);
     2739
     2740        SAFEDELETE_TAB(value);
     2741
     2742        if (J2000) AfficherLog("Mode J2000 activé.\n\n", true);
     2743        else AfficherLog("Mode J2000 désactivé.\n\n", true);
     2744    }
     2745    else
     2746    {
     2747        ErreurLog("Le parametre J2000 est incorrect.\n");
     2748
     2749        return false;
     2750    }
     2751
     2752    // Lecture de la liste des observations
     2753
     2754    section = "objet 1";
     2755    key     = "date";
     2756
     2757
     2758    while ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
     2759            && (numobjets<MAXOBJETS))
     2760    {
     2761        os << "object n°" << numobjets << endl;
     2762        AfficherLog(&os, true);
     2763
     2764        SAFEDELETE_TAB(value);
     2765
     2766
     2767        // Lecture de la date et de l'heure de l'observation
     2768
     2769        key = "date";
     2770
     2771        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
     2772                && (Decomposition(value, 3, &a1, &a2, &a3)))
     2773        {
     2774            AfficherLog("Date du début de l'observation : le " + (string)value, true);
     2775            SAFEDELETE_TAB(value);
     2776
     2777            objets[numobjets].JJ = CalculJJ(a3, a2, a1, 0.0);
     2778        }
     2779        else
     2780        {
     2781            os << "La date de la rubrique [objet " << numobjets << "] est incorrecte !" << endl;
     2782            ErreurLog(&os);
     2783
     2784            return false;
     2785        }
     2786
     2787        key = "heure";
     2788
     2789        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
     2790                && (Decomposition(value, 2, &a1, &a2, &a3)))
     2791        {
     2792            AfficherLog(" à " + (string)value, true) ;
     2793            SAFEDELETE_TAB(value);
     2794
     2795
     2796            objets[numobjets].JJ += ( a1 + a2 / 60.0 + a3 / 3600.0 ) / 24.0;
     2797
     2798            os << " TU  -> JJ=" << fixed << objets[numobjets].JJ << scientific << endl;
     2799
     2800            AfficherLog(&os, true);
     2801
     2802            for (int i=1; i<numobjets; i++)
     2803            {
     2804                if ( objets[i].JJ == objets[numobjets].JJ )
     2805                {
     2806                    os << "Attention, les observations des objets " << i << " et ";
     2807                    os << numobjets << " sont définies à la même date !" << endl;
     2808                    ErreurLog(&os);
     2809                }
     2810
     2811                if ( objets[i].JJ + objets[i].Duree / 3600 / 24.0 > objets[numobjets].JJ )
     2812                {
     2813                    os << "Attention, les observations des objets " << i << " et " ;
     2814                    os << numobjets << " se chevauchent !" << endl;
     2815                    ErreurLog(&os);
     2816                }
     2817            }
     2818        }
     2819        else
     2820        {
     2821            os << "L'heure de la rubrique [objet " << numobjets << "] est incorrecte !" << endl;
     2822            ErreurLog(&os);
     2823
     2824            return false;
     2825        }
     2826
     2827
     2828        // Lecture de la durée de l'observation
     2829
     2830        key = "duree";
     2831
     2832        objets[numobjets].Duree=0.0;
     2833
     2834        if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
     2835        {
     2836            AfficherLog("Durée de l'observation : " + (string)value + " secondes\n", true);
     2837            objets[numobjets].Duree=atof(value);
     2838            SAFEDELETE_TAB(value);
     2839        }
     2840        else
     2841        {
     2842            os << "La duree d'observation de la rubrique [objet " << numobjets << "] est incorrecte !\n";
     2843            ErreurLog(&os);
     2844
     2845            return false;
     2846        }
     2847
     2848        // Lecture de l'ascension droite de l'objet
     2849
     2850        key = "ad";
     2851
     2852        objets[numobjets].ad = "";
     2853
     2854        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
     2855                && (Decomposition(value, 2, NULL, NULL, NULL)))
     2856        {
     2857            AfficherLog("Ascension droite de l'objet : " + (string)value + "\n", true);
     2858            objets[numobjets].ad = value;
     2859            SAFEDELETE_TAB(value);
     2860        }
     2861        else
     2862        {
     2863            os << "L'ascension droite de la rubrique [objet " << numobjets << "] est incorrecte !";
     2864            os << endl;
     2865            ErreurLog(&os);
     2866
     2867            return false;
     2868        }
     2869
     2870        // Lecture de la déclinaison de l'objet
     2871
     2872        key = "de";
     2873
     2874        objets[numobjets].de = "";
     2875
     2876        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
     2877                && (Decomposition(value, 0, NULL, NULL, NULL)))
     2878        {
     2879            AfficherLog("Déclinaison de l'objet : " + (string)value + "\n\n", true);
     2880            objets[numobjets].de = value;
     2881            SAFEDELETE_TAB(value);
     2882        }
     2883        else
     2884        {
     2885            os << "La déclinaison de la rubrique [objet " << numobjets << "] est incorrecte !";
     2886            os << endl;
     2887            ErreurLog(&os);
     2888
     2889            return false;
     2890        }
     2891
     2892        objets[numobjets].exec = false;
     2893
     2894        // On passe à l'objet suivant
     2895
     2896        numobjets++;
     2897
     2898        os << "objet "<< numobjets;
     2899
     2900        section = os.str();
     2901
     2902        os.str("");
     2903    }
     2904
     2905    SAFEDELETE_TAB(value);
     2906
     2907    return true;
     2908}
     2909
     2910
     2911/**************************************************************************************
     2912** chargement du catalogue d'étoiles nécessaire à la procédure d'alignement
     2913**
     2914***************************************************************************************/
     2915
     2916bool BAOcontrol::ChargementCatalogueEtoiles(string fileName)
     2917{
     2918    string section;
     2919    string key;
     2920    char * value   = NULL;
     2921
     2922    stringstream os;
     2923    float a1, a2, a3, h;
     2924
     2925    // Si le fichier n'existe pas -> on sort !
     2926
     2927    if (!is_readable(fileName)) return false;
     2928
     2929    AfficherLog("Chargement du catalogue d'étoiles : ", true);
     2930
     2931    UpdateTime();
     2932
     2933    numEtoiles = 1;
     2934
     2935    // Lecture des étoiles
     2936
     2937    section = "star 1";
     2938    key     = "name";
     2939
     2940    while (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
     2941    {
     2942        // Nom de l'étoile
     2943
     2944        Etoiles[numEtoiles].nom = value;
     2945        SAFEDELETE_TAB(value);
     2946
     2947        // On convertit le nom des étoiles en minuscules
     2948
     2949        for (int i=0; i<strlen(Etoiles[numEtoiles].nom.c_str()); i++) Etoiles[numEtoiles].nom[i] = tolower(Etoiles[numEtoiles].nom[i]);
     2950
     2951
     2952        //Constellation
     2953
     2954        key = "const";
     2955
     2956        readINI(section.c_str(), key.c_str(), &value, fileName.c_str());
     2957
     2958        Etoiles[numEtoiles].cons = value;
     2959        SAFEDELETE_TAB(value);
     2960
     2961
     2962        // Lecture des coordonnées de l'étoile
     2963
     2964        key = "ar";
     2965
     2966        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
     2967                && (Decomposition(value, 2, &a1, &a2, &a3)))
     2968        {
     2969            SAFEDELETE_TAB(value);
     2970
     2971            Etoiles[numEtoiles].ad = (a1 + a2/60.0 + a3/3600.0) * 15.0 * Pidiv180;
     2972        }
     2973        else
     2974        {
     2975            os << "Les coordonnées AR de l'étoile " << numEtoiles << " sont incorrectes !" << endl;
     2976            ErreurLog(&os);
     2977
     2978            return false;
     2979        }
     2980
     2981        key = "de";
     2982
     2983        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
     2984                && (Decomposition(value, 0, &a1, &a2, &a3)))
     2985        {
     2986            Etoiles[numEtoiles].de = (fabs(a1) + a2/60.0 + a3/3600.0 ) * Pidiv180;
     2987
     2988            if (value[0] == '-')  Etoiles[numEtoiles].de = -Etoiles[numEtoiles].de;
     2989
     2990            SAFEDELETE_TAB(value);
     2991        }
     2992        else
     2993        {
     2994            os << "Les coordonnées DE de l'étoile " << numEtoiles << " sont incorrectes !" << endl;
     2995            ErreurLog(&os);
     2996
     2997            return false;
     2998        }
     2999
     3000
     3001        // Lecture de la durée de l'observation
     3002
     3003        key = "mag";
     3004
     3005        if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
     3006        {
     3007            Etoiles[numEtoiles].mag=(double)atof(value);
     3008            SAFEDELETE_TAB(value);
     3009        }
     3010        else
     3011        {
     3012            os << "La magnitude de l'étoile " << numEtoiles << " est incorrecte !\n";
     3013            ErreurLog(&os);
     3014
     3015            return false;
     3016        }
     3017
     3018
     3019        // Passage du repÚre J2000 à l'écliptique et à l'équinoxe liée à la date de l'observation
     3020
     3021        Precession(&Etoiles[numEtoiles].ad, &Etoiles[numEtoiles].de);
     3022        NutationEtoile(&Etoiles[numEtoiles].ad, &Etoiles[numEtoiles].de);
     3023        AberrationAnnuelle(&Etoiles[numEtoiles].ad, &Etoiles[numEtoiles].de);
     3024
     3025
     3026        // On passe à l'objet suivant
     3027
     3028        numEtoiles++;
     3029
     3030        key     = "name";
     3031
     3032        os << "star "<< numEtoiles;
     3033
     3034        section = os.str();
     3035
     3036        os.str("");
     3037    }
     3038
     3039    if (value) SAFEDELETE_TAB(value);
     3040
     3041    os << numEtoiles-1 << " étoiles chargées.\n\n";
     3042
     3043    AfficherLog(os.str(), true);
     3044
     3045    return true;
     3046}
     3047
    22003048
    22013049
     
    22273075    if (argc == 1)  cout << "Tapez help pour obtenir la liste des commandes disponibles.\n" << endl << endl;
    22283076
     3077
    22293078    // On lance la fenêtre graphique
    22303079
     
    22323081
    22333082    XSelectInput(d,w, ExposureMask );
     3083
    22343084
    22353085    // On lance le thread pour gérer la fenêtre graphique
     
    22373087
    22383088    if (pthread_create(&th1, NULL, (void*(*)(void*))LancementThread, this) < 0) {
    2239         Erreur("Impossible de créer le thread\n");
     3089        ErreurLog("Impossible de créer le thread\n");
    22403090        return -1;
    22413091    }
    22423092
    22433093
    2244 
    22453094    // si on a utilisé l'option -r en ligne de commande
    2246     // alors on charge et on lance l'exécution d'un fichier de mouvements
     3095    // alors on charge et on execute le fichier de mouvements
    22473096
    22483097    if (argc == 3)
     
    22633112        else
    22643113        {
    2265             Erreur("Usage incorrect\n\n");
     3114            ErreurLog("Usage incorrect\n\n");
    22663115        }
    22673116    }
     
    22733122        {
    22743123            // Prompt
    2275             ChoixCouleurs==1 ? cout << blue1 : cout << blue2;
     3124            ChoixCouleurs==1 ? IDLog(blue2) : IDLog(blue1);
     3125
    22763126            cout << '>';
     3127
    22773128            // saisie
    22783129            getline(cin, chaine);
    2279             ChoixCouleurs==1 ? cout << grey1 : cout << grey2;
     3130
     3131            ChoixCouleurs==1 ? IDLog(grey1) : IDLog(grey2);
    22803132
    22813133            // on met en minuscules
     
    22833135
    22843136            // on décode et exécute les commandes
    2285             DecodageEntreesUtilisateur(chaine);   
    2286            
     3137            DecodageEntreesUtilisateur(chaine);
     3138
    22873139        }
    22883140        while (NoExit);
    22893141
    22903142        pthread_join(th1 ,NULL);
    2291         //pthread_detach(th1);
    22923143    }
    22933144
    22943145    return 0;
    22953146}
     3147
     3148
     3149/**************************************************************************************
     3150** Le fichier file existe-t-il et n'est-il pas vide ?
     3151**
     3152**************************************************************************************/
     3153
     3154bool BAOcontrol::is_readable( const string & file )
     3155{
     3156    ifstream fichier( file.c_str() );
     3157    if (fichier.fail()) return false;
     3158
     3159    // sauvegarder la position courante
     3160    long pos = fichier.tellg();
     3161    // se placer en fin de fichier
     3162    fichier.seekg( 0 , ios_base::end );
     3163    // récupérer la nouvelle position = la taille du fichier
     3164    long size = fichier.tellg();
     3165    return (size > 0);
     3166}
  • BAORadio/libindi/libindi/BAOControl/baocontrol.h

    r619 r642  
    77
    88
    9 #include <iostream>
    10 #include <string.h>
    11 #include <sstream>
    12 #include "ClientSocket.h"
    13 #include "SocketException.h"
     9#include "math.h"
     10
    1411#include <stdio.h>
    1512#include <stdlib.h>
    1613#include <pthread.h>
    1714#include <X11/Xlib.h>
    18 #include "filetools.h"
    19 #include "../drivers/telescope/astro.h"
    20 #include "math.h"
     15
    2116#include <time.h>
    2217#include <unistd.h>
    2318#include <sys/time.h>
     19#include <termios.h>
    2420
    25 // couleurs utilisées dans le terminal
     21#include "../communs/const.h"
     22#include "../communs/logs.h"
     23#include "../communs/ClientSocket.h"
     24#include "../communs/SocketException.h"
     25#include "../communs/astro.h"
     26#include "../communs/alignement.h"
    2627
    27 #define red1 "\033[0;31m"
    28 #define blue1 "\033[0;34m"
    29 #define green1 "\033[0;32m"
    30 #define black1 "\033[0;30m"
    31 #define grey1 "\033[1;30m"
    32 #define red2 "\033[1;31m"
    33 #define blue2 "\033[1;34m"
    34 #define green2 "\033[1;32m"
    35 #define black2 "\033[1;30m"
    36 #define grey2 "\033[1;37m"
    37 
    38 
    39 // dimensions des tableaux
    40 
    41 #define MAXLOG 1000
    42 #define MAXOBJETS 100
    43 #define MAXANTENNES 50
    44 
    45 
    46 // dimensions de la fenêtre graphique
    47 
    48 #define haut_fenetre 10+22*10
    49 #define larg_fenetre 605
    5028
    5129using namespace std;
    5230
    5331
    54 struct DefAntenne
     32// ParamÚtres des étoiles utilisées pour l'alignement des antennes
     33
     34struct DefEtoiles
    5535{
    56     unsigned char ip;                   // Adresse ip d'une antenne
    57 
    58     char ok;                            // actuellement disponible ?
    59    
    60     long delta_az;
    61    
    62     long delta_ha;
    63 };
    64 
    65 // objets stockés dans le fichier de mouvements
    66 
    67 struct DefObjets
    68 {
    69     double JJ;                          // Date julienne où le télescope doit aller pointer l'objet
    70     double Duree;                       // Durée de l'observation de l'objet en sec
    71     string ad;                          // Ascension droite J2000 de l'objet
    72     string de;                          // déclinaison J2000 de l'objet
    73     bool exec;                          // En cours d'exécution ?
     36    string nom;                         // Nom de l'objet
     37    string cons;                        // Nom de la constellation
     38    double ad;                          // Ascension droite J2000 de l'objet (en rad)
     39    double de;                          // déclinaison J2000 de l'objet (en rad)
     40    double az;                          // Azimut (en rad)
     41    double ha;                          // hauteur au-dessus de l'horizon (en rad)
     42    double mag;                         // magnitude
     43    bool   selectionnee;                // l'objet a-t-il été sélectionné pour calibrer l'antenne
     44                                        // actuellement en mode alignement ?
    7445};
    7546
    7647
    7748
    78 class BAOcontrol : public Astro
     49// structure définissant les paramÚtres des antennes
     50
     51struct DefAntenne
     52{
     53    unsigned char ip;                   // Adresse ip d'une antenne. Seul le dernier nombre nous intéresse
     54
     55    char ok;                            // actuellement disponible ?
     56                                        // 0 = antenne non connectée
     57                                        // 1 = antenne connectée fonctionnant normalement
     58                                        // 2 = antenne connectée mais présentant un défaut
     59
     60    Alignement *AlignementAntenne;      // Contient les paramÚtres d'alignement de l'antenne définie par cette structure 
     61};
     62
     63
     64
     65// objets ou zone du ciel stockés dans le fichier des mouvements planifiés
     66// Se reporter à la notice de la commande run pour savoir comment utiliser ces fichiers de mouvement
     67
     68struct DefObjets
     69{
     70    double JJ;                          // Date julienne du début de l'observation de l'objet i défini dans le fichier de mouvements
     71    double Duree;                       // Durée de l'observation de l'objet en sec
     72    string ad;                          // Ascension droite de l'objet dans le repÚre J2000
     73    string de;                          // Déclinaison de l'objet dans le repÚre J2000
     74    bool exec;                          // L'objet est-il actuellement observé ?
     75};
     76
     77
     78
     79
     80//Classe principale de l'application BAOcontrol
     81
     82class BAOcontrol : public Astro, public Logs
    7983{
    8084
     
    8387    ~BAOcontrol();
    8488
     89    //Gestion du thread
     90   
    8591    void *my_thread_process ();
     92   
     93    // intialise la clase
     94   
    8695    int init(int argc, char **argv);
    8796
    8897
     98
    8999private:
    90     void Affiche(string chaine, bool AfficheEcran);
    91     void Affiche(stringstream *Message, bool AfficheEcran);
    92     void Erreur(string chaine);
    93     void Erreur(stringstream *Message);
     100
     101    // Gestion de la fenêtre graphique
     102
    94103    void initialiserFenetre();
    95104    void Dessiner();
    96105    void rouler();
     106
     107
     108    //communications entre les antennes et le microcontrÃŽleur
     109
    97110    void LireReponse();
    98111    bool VerifReponse(string reponseattendue);
    99     void Update();
    100     bool Decomposition(string chaine, char type, float *a1, float *a2, float *a3);
    101     bool DecompositionCommande(string chaine, string commande, string *chaine1, string *chaine2);
     112    void UpdateTime();
     113
     114
     115    // commandes disponibles
     116   
     117    bool Connect(bool connect);
    102118    bool EnvoyerCoordGeographiques();
     119    bool EnvoyerPressionTemperature();
     120    bool EnvoyerDelaisModesTransitEtTracking();
     121    bool EnvoyerMethodeAlignement();
    103122    bool Park();
    104123    bool Abort();
    105124    bool Goto(string ar, string dec, bool Transit, bool J2000);
    106     bool Connect(bool connect);
     125    bool AlignementAntenneIP(string ip);
     126
     127
     128    // gestion des fichiers
     129
     130    int  readline (FILE * pfile, char *tab);
     131    bool is_readable( const std::string & file );   
    107132    bool LectureFichierMouvements(string fileName);
    108     bool EnregistrementParametresAlignement(string fileName);
     133    bool ChargementCatalogueEtoiles(string fileName);
     134    bool ChargementParametres(string fileName);
     135   
     136
     137    //Gestion serveur NED
     138   
     139    CoordonneesHoraires ServeurNED(string objet);
     140   
     141
     142    // Routines principales
     143
     144    bool Decomposition(string chaine, char type, float *a1, float *a2, float *a3);
     145    bool DecompositionCommande(string chaine, string commande, string *chaine1, string *chaine2);
    109146    void DecodageEntreesUtilisateur(string chaine);
    110147    bool Run(string fichier);
    111     bool ChargementParametres(string fileName);
    112     Coordonnees ServeurNED(string objet);
    113     int  readline (FILE * pfile, char *tab);
    114     bool Alignement(string ip);
    115148
     149 
    116150
    117151
    118152    // Variables globales
    119153
    120     XFontStruct * fd;                           // Police de caractÚres dans la fenêtre graphique
    121 
    122     char ChoixCouleurs;                         // 1-pour un terminal à fond blanc    2-pour un terminal à fond noir
     154    XFontStruct * fd;                           // Police de caractÚres utilisée dans la fenêtre graphique
    123155
    124156    string logs[MAXLOG];                        // Sauvegarde de toutes les actions et réponses dans un tableau logs
     
    130162    int numobjets;                              // Nbre d'objets dans le dernier fichier de mouvements chargé
    131163    int runnum;                                 // Numéro de l'objet actuellement visé dans le fichier de mouvement
     164    int numEtoiles;                             // Nbre d'étoiles utilisées pour la procédure d'alignement des antennes
     165    int MethodeAlignement;                      // Méthode d'alignement utilisée
     166   
    132167
    133168    double Pression;                            // Pression atmosphérique en mBar
     
    139174    bool exitrun;                               // doit-on sortir du programme à la fin de l'execution de la commande run ?
    140175    bool J2000;                                 // est-ce que les coordonnées du fichier de mouvements sont en coordonnées J2000 ?
     176    bool ModificationAlignement;                // Est-ce que l'une des antennes est en cours d'alignement et est-ce qu'un paramÚtre
     177                                                // d'alignement à changé ?
    141178
    142179    struct DefAntenne *Antennes;                // Sauvegarde de la situation actuelle de l'antenne i
    143180    struct DefObjets  *objets;                  // Liste des objets chargés depuis un fichier de mouvements
     181    struct DefEtoiles *Etoiles;                 // Liste des étoiles servant à la procédure d'alignement des antennes
    144182
    145183    string LatitudeChar;                        // Latitude du lieu d'observation. Chargée depuis le fichier de configuration
    146184    string LongitudeChar;                       // Longitude du lieu d'observation. Chargée depuis le fichier de configuration
    147     string Serveur;                             // Nom ou IP du serveur faisant tourner indi_BAO. Par defaut c'est localhost
     185    string Serveur;                             // Nom ou IP du serveur faisant tourner indi_BAO. Par defaut contient 'localhost'
    148186    string Port;                                // Port utilisé pour connecter le serveur indi_BAO
    149187
     
    153191    Window w;                                   // fenêtre graphique
    154192    Pixmap db;                                  // copie de la fenêtre pour permettre une actualisation sans scintillement
     193   
    155194    GC noir, vert, rouge, gris;                 // couleurs utilisées dans la fenêtre graphique
    156 
    157195};
    158196
  • BAORadio/libindi/libindi/BAOControl/main.cpp

    r504 r642  
    99  appli->init(argc, argv);
    1010 
    11   delete appli;
    12  
     11  delete appli; 
    1312}
  • BAORadio/libindi/libindi/BAOTest/BAOtest_main.cpp

    r504 r642  
    55***************************************************************************************/
    66
    7 #include "ClientSocket.h"
    8 #include "ServerSocket.h"
    9 #include "SocketException.h"
     7#include "../communs/ClientSocket.h"
     8#include "../communs/SocketException.h"
    109#include <iostream>
    1110#include <string>
     
    128127#define ERREURS 50
    129128
    130 int main ( int argc, int argv[] )
     129int main ( int argc, char *argv[] )
    131130{
    132131    Position Pos, Pos2;
  • BAORadio/libindi/libindi/BAOTest/Makefile

    r495 r642  
    22#
    33
    4 simple_server_objects = ServerSocket.o Socket.o simple_server_main.o
    5 simple_client_objects = ClientSocket.o Socket.o simple_client_main.o
    6 BAOtest_objects = ClientSocket.o ServerSocket.o Socket.o BAOtest_main.o
     4BAOtest_objects = BAOtest_main.o
    75
    86
    9 all : simple_server simple_client BAOtest
     7all : BAOtest
    108
    11 simple_server: $(simple_server_objects)
    12         g++ -o simple_server $(simple_server_objects)
     9BAOtest: $(BAOtest_objects)
     10        g++ $(CXXFLAGS) -c -o ../BAOTest/Socket.o ../communs/Socket.cpp
     11        g++ $(CXXFLAGS) -c -o ../BAOTest/ClientSocket.o ../communs/ClientSocket.cpp
     12        g++ -o BAOtest $(BAOtest_objects) Socket.o ClientSocket.o
    1313
    1414
    15 simple_client: $(simple_client_objects)
    16         g++ -o simple_client $(simple_client_objects)
    17 
    18 BAOtest: $(BAOtest_objects)
    19         g++ -o BAOtest $(BAOtest_objects)
    20 
    21 
    22 Socket: Socket.cpp
    23 ServerSocket: ServerSocket.cpp
    2415ClientSocket: ClientSocket.cpp
    25 simple_server_main: simple_server_main.cpp
    26 simple_client_main: simple_client_main.cpp
    2716BAOtest_main: BAOtest_main.cpp
    2817
    2918clean:
    30         rm -f *.o *.cpp~ *.h~ simple_server simple_client BAOtest
     19        rm -f *.o *.cpp~ *.h~  BAOtest
     20
     21install:
     22        cp BAOtest /usr/bin
  • BAORadio/libindi/libindi/CMakeLists.txt

    r619 r642  
    11cmake_minimum_required(VERSION 2.4.7)
     2PROJECT(libindi C CXX)
    23
    34##################  INDI version  ################################
    45set(INDI_SOVERSION "0")
    56set(CMAKE_INDI_VERSION_MAJOR 0)
    6 set(CMAKE_INDI_VERSION_MINOR 8)
     7set(CMAKE_INDI_VERSION_MINOR 9)
    78set(CMAKE_INDI_VERSION_RELEASE 0)
    89set(CMAKE_INDI_VERSION_STRING "${CMAKE_INDI_VERSION_MAJOR}.${CMAKE_INDI_VERSION_MINOR}.${CMAKE_INDI_VERSION_RELEASE}")
     
    1314set(BIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin")
    1415set(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include")
    15 
    16 MESSAGE( STATUS "BIN_INSTALL_DIR: " ${BIN_INSTALL_DIR} )
    1716
    1817##################  setup install directories  ################################
     
    3029include (CheckIncludeFiles)
    3130
    32 find_package(ZLIB REQUIRED)
    33 
    34 FIND_PACKAGE(Boost)
    35 IF (BOOST_FOUND)
    36     INCLUDE_DIRECTORIES(${BOOST_INCLUDE_DIR})
    37 ENDIF()
    38 
    39 
    40 macro_optional_find_package(USB)
    41 macro_log_feature(LIBUSB_FOUND "libusb" "User level access to USB devices" "http://www.libusb.org" FALSE "" "Provides support for USB based drivers in INDI.")
    42 
    43 macro_optional_find_package(CFITSIO)
     31FIND_PACKAGE(ZLIB REQUIRED)
     32FIND_PACKAGE(USB REQUIRED)
     33FIND_PACKAGE(CFITSIO REQUIRED)
    4434
    4535if (NOT CFITSIO_FOUND OR CFITSIO_VERSION_MAJOR LESS 3)
     
    4838
    4939macro_bool_to_01(CFITSIO_FOUND HAVE_CFITSIO_H)
    50 macro_log_feature(CFITSIO_FOUND "libcfitsio" "A library for reading and writing data files in FITS (Flexible Image Transport System) data format" "http://indi.sf.net" FALSE "3.03" "Provides INDI with FITS I/O support.")
    51 
     40macro_log_feature(CFITSIO_FOUND "libcfitsio" "A library for reading and writing data files in FITS (Flexible Image Transport System) data format" "http://heasarc.gsfc.nasa.gov/fitsio/fitsio.html" FALSE "3.03" "Provides INDI with FITS I/O support.")
    5241
    5342macro_optional_find_package(Nova)
    5443macro_bool_to_01(NOVA_FOUND HAVE_NOVA_H)
    55 macro_log_feature(NOVA_FOUND "libnova" "A general purpose, double precision, Celestial Mechanics, Astrometry and Astrodynamics library" "http://indi.sf.net" FALSE "0.12.1" "Provides INDI with astrodynamics library.")
     44macro_log_feature(NOVA_FOUND "libnova" "A general purpose, double precision, Celestial Mechanics, Astrometry and Astrodynamics library" "http://libnova.sourceforge.net" FALSE "0.12.1" "Provides INDI with astrodynamics library.")
    5645
    5746check_include_files(linux/videodev2.h HAVE_LINUX_VIDEODEV2_H)
     
    112101        ${CMAKE_SOURCE_DIR}/libs/indibase/indifocuser.cpp
    113102        ${CMAKE_SOURCE_DIR}/libs/indibase/indiusbdevice.cpp
     103        ${CMAKE_SOURCE_DIR}/libs/indibase/indiguiderinterface.cpp
     104        ${CMAKE_SOURCE_DIR}/libs/indibase/indifilterinterface.cpp
     105
    114106    )
    115107
     
    121113set(indiserver_SRCS indiserver.c fq.c)
    122114
    123 add_executable(indiserver ${indiserver_SRCS}  ${liblilxml_SRCS})
    124 
    125 target_link_libraries(indiserver  pthread )
     115add_executable(indiserver ${indiserver_SRCS} ${liblilxml_SRCS})
     116
     117target_link_libraries(indiserver pthread)
    126118
    127119if (NOVA_FOUND)
     
    129121endif (NOVA_FOUND)
    130122
    131 install(TARGETS indiserver RUNTIME DESTINATION bin )
     123install(TARGETS indiserver RUNTIME DESTINATION bin)
    132124
    133125#################################################
     
    146138endif(CFITSIO_FOUND)
    147139
    148 install(TARGETS indi LIBRARY DESTINATION lib${LIB_POSTFIX})
     140install(TARGETS indi LIBRARY DESTINATION ${LIB_DESTINATION})
    149141set_target_properties(indi PROPERTIES VERSION ${CMAKE_INDI_VERSION_STRING} SOVERSION ${INDI_SOVERSION})
    150142
     
    154146##################################################
    155147add_library(indimain STATIC ${indimain_SRCS})
    156 install(TARGETS indimain ARCHIVE DESTINATION lib${LIB_POSTFIX})
     148install(TARGETS indimain ARCHIVE DESTINATION ${LIB_DESTINATION})
    157149
    158150##################################################
     
    161153##################################################
    162154add_library(indidriver STATIC ${indimain_SRCS} ${indidriver_SRCS})
    163 install(TARGETS indidriver ARCHIVE DESTINATION lib${LIB_POSTFIX})
     155install(TARGETS indidriver ARCHIVE DESTINATION ${LIB_DESTINATION})
    164156
    165157##################################################
     
    168160add_library(indiclient STATIC ${indiclient_SRCS})
    169161target_link_libraries(indiclient indi pthread)
    170 install(TARGETS indiclient ARCHIVE DESTINATION lib${LIB_POSTFIX})
     162install(TARGETS indiclient ARCHIVE DESTINATION ${LIB_DESTINATION})
    171163
    172164#####################################
     
    200192   ${CMAKE_SOURCE_DIR}/drivers/telescope/lx200classic.cpp
    201193   ${CMAKE_SOURCE_DIR}/drivers/telescope/lx200apdriver.c
    202    ${CMAKE_SOURCE_DIR}/drivers/telescope/lx200ap.cpp )
     194   ${CMAKE_SOURCE_DIR}/drivers/telescope/lx200ap.cpp
     195   ${CMAKE_SOURCE_DIR}/drivers/telescope/lx200fs2.cpp)
    203196
    204197add_executable(indi_lx200generic ${lx200generic_SRCS}  ${liblilxml_SRCS} ${libindicom_SRCS})
     
    213206
    214207file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/make_lx200generic_symlink.cmake
    215 "exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic ${BUILD_ROOT}${BIN_INSTALL_DIR}/indi_lx200classic)\n
    216 exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic ${BUILD_ROOT}${BIN_INSTALL_DIR}/indi_lx200autostar)\n
    217 exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic ${BUILD_ROOT}${BIN_INSTALL_DIR}/indi_lx200_16)\n
    218 exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic ${BUILD_ROOT}${BIN_INSTALL_DIR}/indi_lx200gps)\n
    219 exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic ${BUILD_ROOT}${BIN_INSTALL_DIR}/indi_lx200ap)\n
     208"exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic \$ENV{DESTDIR}${BIN_INSTALL_DIR}/indi_lx200classic)\n
     209exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic \$ENV{DESTDIR}${BIN_INSTALL_DIR}/indi_lx200autostar)\n
     210exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic \$ENV{DESTDIR}${BIN_INSTALL_DIR}/indi_lx200_16)\n
     211exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic \$ENV{DESTDIR}${BIN_INSTALL_DIR}/indi_lx200gps)\n
     212exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic \$ENV{DESTDIR}${BIN_INSTALL_DIR}/indi_lx200ap)\n
     213exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic \$ENV{DESTDIR}${BIN_INSTALL_DIR}/indi_lx200fs2)\n
    220214")
    221215set_target_properties(indi_lx200generic PROPERTIES POST_INSTALL_SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/make_lx200generic_symlink.cmake)
     
    311305set(BAO_SRCS
    312306   ${indimain_SRCS}
    313 ${CMAKE_SOURCE_DIR}/drivers/telescope/Socket.cpp
    314 ${CMAKE_SOURCE_DIR}/drivers/telescope/ServerSocket.cpp
    315 ${CMAKE_SOURCE_DIR}/drivers/telescope/astro.cpp
     307${CMAKE_SOURCE_DIR}/communs/Socket.cpp
     308${CMAKE_SOURCE_DIR}/communs/ServerSocket.cpp
     309${CMAKE_SOURCE_DIR}/communs/astro.cpp
     310${CMAKE_SOURCE_DIR}/communs/exception.cpp
     311${CMAKE_SOURCE_DIR}/communs/filetools.cpp
     312${CMAKE_SOURCE_DIR}/communs/alignement.cpp
     313${CMAKE_SOURCE_DIR}/communs/logs.cpp
    316314${CMAKE_SOURCE_DIR}/drivers/telescope/BAO.cpp
    317 ${CMAKE_SOURCE_DIR}/drivers/telescope/exception.c
    318 ${CMAKE_SOURCE_DIR}/drivers/telescope/filetools.cpp
    319315 )
    320316   
     
    329325
    330326install(TARGETS indi_BAO RUNTIME DESTINATION bin )
    331 
    332327########### Syncscan ###############
    333328set(synscan_SRCS
     
    344339
    345340install(TARGETS indi_synscan RUNTIME DESTINATION bin )
     341
     342########### Magellan I #############
     343set(magellan_SRCS
     344   ${indimain_SRCS}
     345   ${CMAKE_SOURCE_DIR}/drivers/telescope/magellandriver.c
     346   ${CMAKE_SOURCE_DIR}/drivers/telescope/magellan1.cpp )
     347
     348add_executable(indi_magellan1 ${magellan_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS})
     349
     350if (NOVA_FOUND)
     351  target_link_libraries(indi_magellan1 ${NOVA_LIBRARIES})
     352endif (NOVA_FOUND)
     353
     354install(TARGETS indi_magellan1 RUNTIME DESTINATION bin )
     355
     356########### IEQ45 #############
     357set(ieq45_SRCS
     358   ${indimain_SRCS}
     359   ${CMAKE_SOURCE_DIR}/drivers/telescope/ieq45driver.c
     360   ${CMAKE_SOURCE_DIR}/drivers/telescope/ieq45.cpp )
     361
     362add_executable(indi_ieq45 ${ieq45_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS})
     363
     364if (NOVA_FOUND)
     365  target_link_libraries(indi_ieq45 ${NOVA_LIBRARIES})
     366endif (NOVA_FOUND)
     367
     368install(TARGETS indi_ieq45 RUNTIME DESTINATION bin )
    346369
    347370########### Telescope Simulator ##############
     
    361384install(TARGETS indi_simulator_telescope RUNTIME DESTINATION bin )
    362385
     386########### CCD Simulator ##############
     387if (CFITSIO_FOUND)
     388
     389set(ccdsimulator_SRCS
     390        ${indimain_SRCS}
     391        ${CMAKE_SOURCE_DIR}/drivers/ccd/ccd_simulator.cpp
     392   )
     393
     394add_executable(indi_simulator_ccd ${ccdsimulator_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS})
     395
     396target_link_libraries(indi_simulator_ccd indidriver ${CFITSIO_LIBRARIES} m z pthread)
     397
     398if (NOVA_FOUND)
     399  target_link_libraries(indi_simulator_ccd ${NOVA_LIBRARIES})
     400endif (NOVA_FOUND)
     401
     402install(TARGETS indi_simulator_ccd RUNTIME DESTINATION bin )
     403
     404endif (CFITSIO_FOUND)
     405
     406
    363407#####################################
    364408########## FOCUSER GROUP ############
    365409#####################################
    366410
    367 ########### CCD Simulator ##############
    368 if (CFITSIO_FOUND)
    369 
    370 set(ccdsimulator_SRCS
    371         ${indimain_SRCS}
    372         ${CMAKE_SOURCE_DIR}/drivers/ccd/ccd_simulator.cpp
    373    )
    374 
    375 add_executable(indi_simulator_ccd ${ccdsimulator_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS})
    376 
    377 target_link_libraries(indi_simulator_ccd indidriver ${CFITSIO_LIBRARIES} m z pthread)
    378 
    379 if (NOVA_FOUND)
    380   target_link_libraries(indi_simulator_ccd ${NOVA_LIBRARIES})
    381 endif (NOVA_FOUND)
    382 
    383 install(TARGETS indi_simulator_ccd RUNTIME DESTINATION bin )
    384 
    385 endif (CFITSIO_FOUND)
    386 
    387 
    388 #####################################
    389 ########## FOCUSER GROUP ############
    390 #####################################
    391 
    392411#################################################################################
    393412
     
    396415set(robofocus_SRCS
    397416        ${indimain_SRCS}
    398         ${CMAKE_SOURCE_DIR}/drivers/focuser/robofocus.c
    399         ${CMAKE_SOURCE_DIR}/drivers/focuser/robofocusdriver.c
     417        ${CMAKE_SOURCE_DIR}/drivers/focuser/robofocus.cpp
    400418   )
    401419
    402420add_executable(indi_robo_focus ${robofocus_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS})
    403421
    404 target_link_libraries(indi_robo_focus m)
     422target_link_libraries(indi_robo_focus indidriver m z)
    405423
    406424if (NOVA_FOUND)
     
    428446
    429447file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/make_tcfs_symlink.cmake
    430 "exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_tcfs_focus ${BUILD_ROOT}${BIN_INSTALL_DIR}/indi_tcfs3_focus)\n")
     448"exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_tcfs_focus \$ENV{DESTDIR}${BIN_INSTALL_DIR}/indi_tcfs3_focus)\n")
    431449set_target_properties(indi_tcfs_focus PROPERTIES POST_INSTALL_SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/make_tcfs_symlink.cmake)
    432450
     
    741759${CMAKE_SOURCE_DIR}/libs/indibase/indiccd.h  ${CMAKE_SOURCE_DIR}/libs/indibase/indifilterwheel.h
    742760${CMAKE_SOURCE_DIR}/libs/indibase/indifocuser.h  ${CMAKE_SOURCE_DIR}/libs/indibase/inditelescope.h
    743 ${CMAKE_SOURCE_DIR}/libs/indibase/baseclient.h ${CMAKE_SOURCE_DIR}/libs/indicom.h
    744 ${CMAKE_SOURCE_DIR}/libs/indibase/indiusbdevice.h
     761${CMAKE_SOURCE_DIR}/libs/indibase/baseclient.h ${CMAKE_SOURCE_DIR}/libs/indibase/indiguiderinterface.h
     762${CMAKE_SOURCE_DIR}/libs/indibase/indifilterinterface.h
     763${CMAKE_SOURCE_DIR}/libs/indicom.h ${CMAKE_SOURCE_DIR}/libs/indibase/indiusbdevice.h
    745764 DESTINATION ${INCLUDE_INSTALL_DIR}/libindi COMPONENT Devel)
    746765
  • BAORadio/libindi/libindi/ChangeLog

    r504 r642  
     1From 0.8 to 0.9
     2
     3      # iEQ45 GoTo German Equatorial Mount Driver.
     4      # INDI::Base drivers are now used for most classes of astrnomical instruments.
     5      # New improved QSI CCD & Filter driver.
     6      # New improved Starlight Xpress CCD & Filter driver.
     7      # New improved RoboFocus driver.
     8      # libboost is no longer required to build libindi.
     9      # Numerous bug fixes and minor improvements.
     10
    111From 0.7.2 to 0.8
    212
  • BAORadio/libindi/libindi/Doxyfile

    r501 r642  
    66DOXYFILE_ENCODING      = UTF-8
    77PROJECT_NAME           = "Instrument Neutral Distributed Interface INDI"
    8 PROJECT_NUMBER         = 0.7
     8PROJECT_NUMBER         = 0.9
    99OUTPUT_DIRECTORY       = /home/jasem/Projects/doc
    1010CREATE_SUBDIRS         = NO
  • BAORadio/libindi/libindi/INSTALL

    r504 r642  
    1 INDI Library Setup 0.8.0
     1INDI Library Setup 0.9.0
    22========================
    33
     
    1919+ libusb
    2020+ libnova >= 0.12.2
    21 + libfli  >= 1.7
    2221+ cfitsio >= 3.0
    2322
  • BAORadio/libindi/libindi/Indi_Stellarium/src/Makefile

    r623 r642  
    5454
    5555clean:
    56         rm *.o *.obj
     56        rm *.o TelescopeServerBAO
    5757
    5858make.dep:
  • BAORadio/libindi/libindi/README

    r504 r642  
    1 libindi v0.8
     1libindi v0.9
    22============
    33
  • BAORadio/libindi/libindi/cmake_modules/FindAPOGEE.cmake

    r490 r642  
    5252  else (APOGEE_FOUND)
    5353    if (APOGEE_FIND_REQUIRED)
    54       message(FATAL_ERROR "libapogee not found. Cannot compile Apogee CCD Driver. Please install libapogee and try again. http://APOGEE.sf.net")
     54      message(FATAL_ERROR "libapogee not found. Cannot compile Apogee CCD Driver. Please install libapogee and try again. http://www.indilib.org")
    5555    endif (APOGEE_FIND_REQUIRED)
    5656  endif (APOGEE_FOUND)
  • BAORadio/libindi/libindi/cmake_modules/FindINDI.cmake

    r504 r642  
    6060  )
    6161
    62   if(INDI_INCLUDE_DIR AND INDI_DATA_DIR AND INDI_LIBRARIES AND INDI_DRIVER_LIBRARIES AND INDI_MAIN_LIBRARIES)
    63     set(INDI_FOUND TRUE)
    64   else (INDI_INCLUDE_DIR AND INDI_DATA_DIR AND INDI_LIBRARIES AND INDI_DRIVER_LIBRARIES AND INDI_MAIN_LIBRARIES)
    65     set(INDI_FOUND FALSE)
    66   endif(INDI_INCLUDE_DIR AND INDI_DATA_DIR AND INDI_LIBRARIES AND INDI_DRIVER_LIBRARIES AND INDI_MAIN_LIBRARIES)
     62  # Find pkg-config
     63  FIND_PROGRAM(PKGCONFIG_EXECUTABLE NAMES pkg-config PATHS /usr/bin/ /usr/local/bin )
     64
     65  # query pkg-config asking for a libindi >= 0.8.0
     66     EXEC_PROGRAM(${PKGCONFIG_EXECUTABLE} ARGS --atleast-version=0.8.0 libindi RETURN_VALUE _return_VALUE OUTPUT_VARIABLE _pkgconfigDevNull )
     67     if(_return_VALUE STREQUAL "0")
     68        set(INDI_FOUND TRUE)
     69     else(_return_VALUE STREQUAL "0")
     70       set(INDI_FOUND FALSE)
     71       message(STATUS "Could NOT find libindi. pkg-config indicates that libindi >= 0.8.0 is not installed.")
     72     endif(_return_VALUE STREQUAL "0")
    6773
    6874
     
    7278      message(STATUS "INDI Include: ${INDI_INCLUDE_DIR}, INDI Data: ${INDI_DATA_DIR}")
    7379    endif (NOT INDI_FIND_QUIETLY)
    74   else (INDI_FOUND)
    75     if (INDI_FIND_REQUIRED)
    76       message(FATAL_ERROR "indi-dev not found. Cannot compile INDI drivers. Please install indi-dev and try again. http://www.indilib.org")
    77     endif (INDI_FIND_REQUIRED)
    7880  endif (INDI_FOUND)
    7981
  • BAORadio/libindi/libindi/drivers.xml

    r504 r642  
    11<devGroup group="Telescopes">
    2         <device label="BAO" focal_length="" aperture="">
     2        <device label="BAO" focal_length="" aperture="">
    33                <driver name="BAO">indi_BAO</driver>
    44                <version>1.0</version>
     
    108108                <version>1.0</version>
    109109        </device>
     110        <device label="Magellan I" focal_length="" aperture="">
     111                <driver name="Magellan I">indi_magellan1</driver>
     112                <version>1.0</version>
     113        </device>
     114        <device label="iEQ45" focal_length="" aperture="">
     115                <driver name="IEQ45">indi_ieq45</driver>
     116                <version>0.1</version>
     117        </device>
    110118        <device label="Telescope Simulator" focal_length="" aperture="">
    111119                <driver name="Telescope Simulator">indi_simulator_telescope</driver>
     
    114122</devGroup>
    115123<devGroup group="Focusers">
    116         <device label="Robo Focus">
    117                 <driver name="Robofocus">indi_robo_focus</driver>
    118                 <version>0.1</version>
     124        <device label="RoboFocus">
     125                <driver name="RoboFocus">indi_robo_focus</driver>
     126                <version>1.0</version>
    119127        </device>
    120128        <device label="Optec TCF-S">
     
    130138        <device label="CCD Simulator">
    131139                <driver name="CCD Simulator">indi_simulator_ccd</driver>
    132                 <version>0.1</version>
     140                <version>1.0</version>
    133141        </device>
    134142</devGroup>
    135143<devGroup group="Filter Wheels">
    136         <device label="FLI Wheel">
    137                 <driver name="FLI Wheel">indi_fli_wheel</driver>
    138                 <version>0.9</version>
    139         </device>
    140144        <device label="TruTech Wheel">
    141145                <driver name="TruTech Wheel">indi_trutech_wheel</driver>
     
    144148        <device label="Filter Simulator">
    145149                <driver name="Filter Simulator">indi_simulator_wheel</driver>
    146                 <version>0.1</version>
     150                <version>1.0</version>
    147151        </device>
    148152</devGroup>
  • BAORadio/libindi/libindi/drivers/ccd/ccd_simulator.cpp

    r504 r642  
    22  Copyright(c) 2010 Gerry Rozema. All rights reserved.
    33
    4   This program is free software; you can redistribute it and/or modify it
    5   under the terms of the GNU General Public License as published by the Free
    6   Software Foundation; either version 2 of the License, or (at your option)
    7   any later version.
    8 
    9   This program is distributed in the hope that it will be useful, but WITHOUT
    10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    12   more details.
    13 
    14   You should have received a copy of the GNU General Public License along with
    15   this program; if not, write to the Free Software Foundation, Inc., 59
    16   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    17 
    18   The full GNU General Public License is included in this distribution in the
    19   file called LICENSE.
     4 This library is free software; you can redistribute it and/or
     5 modify it under the terms of the GNU Library General Public
     6 License version 2 as published by the Free Software Foundation.
     7 .
     8 This library is distributed in the hope that it will be useful,
     9 but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     11 Library General Public License for more details.
     12 .
     13 You should have received a copy of the GNU Library General Public License
     14 along with this library; see the file COPYING.LIB.  If not, write to
     15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     16 Boston, MA 02110-1301, USA.
    2017*******************************************************************************/
    2118#include "ccd_simulator.h"
     
    8481void ISSnoopDevice (XMLEle *root)
    8582{
    86     INDI_UNUSED(root);
     83    ISInit();
     84    ccdsim->ISSnoopDevice(root);
    8785}
    8886
     
    125123    TimeFactor=1;
    126124
     125    SimulatorSettingsNV = new INumberVectorProperty;
     126    TimeFactorSV = new ISwitchVectorProperty;
     127
    127128}
    128129
    129130bool CCDSim::SetupParms()
    130131{
     132    int nbuf;
    131133    SetCCDParams(SimulatorSettingsN[0].value,SimulatorSettingsN[1].value,16,SimulatorSettingsN[2].value,SimulatorSettingsN[3].value);
    132134    //  Kwiq
     
    141143    seeing=SimulatorSettingsN[9].value;        //  we get real fat stars in this one
    142144
    143 
    144     if(RawFrame != NULL) delete RawFrame;
    145     RawFrameSize=XRes*YRes;                 //  this is pixel count
    146     RawFrameSize=RawFrameSize*2;            //  Each pixel is 2 bytes
    147     RawFrameSize+=512;                      //  leave a little extra at the end
    148     RawFrame=new char[RawFrameSize];
     145    nbuf = PrimaryCCD.getXRes() * PrimaryCCD.getYRes() * PrimaryCCD.getBPP();
     146    nbuf += 512;
     147    PrimaryCCD.setFrameBufferSize(nbuf);
    149148
    150149    return true;
     
    154153{
    155154
     155    int nbuf;
    156156    SetupParms();
    157157
    158     if(HasGuideHead) {
     158    if(HasGuideHead)
     159    {
    159160        SetGuidHeadParams(500,290,8,9.8,12.6);
    160         RawGuideSize=GXRes*GYRes;                 //  this is pixel count
    161         RawGuideSize+=512;                      //  leave a little extra at the end
    162         RawGuiderFrame=new char[RawGuideSize];
     161        nbuf = GuideCCD.getXRes() * GuideCCD.getYRes();
     162        GuideCCD.setFrameBufferSize(nbuf);
    163163    }
    164164
     
    174174const char * CCDSim::getDefaultName()
    175175{
    176     //fprintf(stderr,"Arrived in getDefaultName and deviceName returns '%s'\n",deviceName());
    177     //if(strlen(deviceName())==0) {
    178176        return (char *)"CCD Simulator";
    179     //} else {
    180     //    char n[500];
    181     //    strcpy(n,deviceName());
    182     //    return n;
    183     //}
    184177}
    185178
     
    190183    INDI::CCD::initProperties();
    191184
    192     IUFillNumber(&EqN[0],"RA","Ra (hh:mm:ss)","%010.6m",0,24,0,0);
    193     IUFillNumber(&EqN[1],"DEC","Dec (dd:mm:ss)","%010.6m",-90,90,0,0);
    194     IUFillNumberVector(&EqNV,EqN,2,"","EQUATORIAL_EOD_COORD","Eq. Coordinates","Main Control",IP_RW,60,IPS_IDLE);
    195     //IUFillNumberVector(&EqNV,EqN,2,deviceName(),"EQUATORIAL_EOD_COORD","Eq. Coordinates","Main Control",IP_RW,60,IPS_IDLE);
    196 
    197     SimulatorSettingsNV = new INumberVectorProperty;
    198     IUFillNumber(&SimulatorSettingsN[0],"SIM_XRES","CCD X resolution","%4.0f",0,2048,0,1280);
    199     IUFillNumber(&SimulatorSettingsN[1],"SIM_YRES","CCD Y resolution","%4.0f",0,2048,0,1024);
     185    IUFillNumber(&SimulatorSettingsN[0],"SIM_PrimarCCD.getXRes()","CCD X resolution","%4.0f",0,2048,0,1280);
     186    IUFillNumber(&SimulatorSettingsN[1],"SIM_PrimarCCD.getYRes()","CCD Y resolution","%4.0f",0,2048,0,1024);
    200187    IUFillNumber(&SimulatorSettingsN[2],"SIM_XSIZE","CCD X Pixel Size","%4.2f",0,60,0,5.2);
    201188    IUFillNumber(&SimulatorSettingsN[3],"SIM_YSIZE","CCD Y Pixel Size","%4.2f",0,60,0,5.2);
     
    209196    IUFillNumber(&SimulatorSettingsN[11],"SIM_SKYGLOW","Sky Glow (magnitudes)","%4.1f",0,6000,0,19.5);
    210197    IUFillNumber(&SimulatorSettingsN[12],"SIM_OAGOFFSET","Oag Offset (arminutes)","%4.1f",0,6000,0,0);
    211     IUFillNumberVector(SimulatorSettingsNV,SimulatorSettingsN,13,deviceName(),"SIMULATOR_SETTINGS","Simulator Settings","SimSettings",IP_RW,60,IPS_IDLE);
    212 
    213 
    214     TelescopeTV = new ITextVectorProperty;
    215     IUFillText(&TelescopeT[0],"ACTIVE_TELESCOPE","Telescope","");
    216     IUFillTextVector(TelescopeTV,TelescopeT,1,deviceName(),"ACTIVE_DEVICES","Snoop Scope","Simulator Config",IP_RW,60,IPS_IDLE);
    217 
    218     TimeFactorSV = new ISwitchVectorProperty;
     198    IUFillNumberVector(SimulatorSettingsNV,SimulatorSettingsN,13,deviceName(),"SIMULATOR_SETTINGS","Simulator Settings","Simulator Config",IP_RW,60,IPS_IDLE);
     199
    219200
    220201    IUFillSwitch(&TimeFactorS[0],"1X","Actual Time",ISS_ON);
     
    224205
    225206
    226     loadConfig();
     207    //loadConfig();
    227208
    228209    return true;
     
    238219    defineNumber(SimulatorSettingsNV);
    239220    defineSwitch(TimeFactorSV);
    240     defineText(TelescopeTV);
    241221    //IDDefText(&ConfigFileTV, NULL);
    242222    //IDDefSwitch(&ConfigSaveRestoreSV, NULL);
     
    257237bool CCDSim::Disconnect()
    258238{
    259     delete RawFrame;
    260     RawFrameSize=0;
    261     RawFrame=NULL;
    262 
    263 
    264     if(RawGuiderFrame != NULL) {
    265         delete RawGuiderFrame;
    266         RawGuideSize=0;
    267     }
    268 
    269239    return true;
    270240}
     
    335305        float timeleft;
    336306        timeleft=CalcTimeLeft(ExpStart,ExposureRequest);
     307
     308        if (timeleft < 0)
     309             timeleft = 0;
     310
     311        PrimaryCCD.setExposure(timeleft);
     312        //ImageExposureN[0].value = timeleft;
     313        //IDSetNumber(ImageExposureNP, NULL);
     314
    337315        if(timeleft < 1.0)
    338316        {
     
    347325        }
    348326    }
     327
    349328    if(InGuideExposure)
    350329    {
    351330        float timeleft;
    352331        timeleft=CalcTimeLeft(GuideExpStart,GuideExposureRequest);
     332
     333
     334        if (timeleft < 0)
     335             timeleft = 0;
     336
     337        //ImageExposureN[0].value = timeleft;
     338        //IDSetNumber(ImageExposureNP, NULL);
     339        GuideCCD.setExposure(timeleft);
     340
    353341        if(timeleft < 1.0)
    354342        {
     
    390378    unsigned short int val;
    391379
    392     ptr=(unsigned short int *)RawFrame;
    393 
    394     if(ShowStarField) {
     380    ptr=(unsigned short int *) PrimaryCCD.getFrameBuffer();
     381
     382    if(ShowStarField)
     383    {
    395384        char gsccmd[250];
    396385        FILE *pp;
     
    423412
    424413        //  Start by clearing the frame buffer
    425         memset(RawFrame,0,RawFrameSize);
     414        memset(PrimaryCCD.getFrameBuffer(),0,PrimaryCCD.getFrameBufferSize());
    426415
    427416
     
    439428        //  no offset or rotation for and y axis means
    440429        pb=0.0;
    441         pc=XRes/2/BinX;
     430        pc=PrimaryCCD.getXRes()/2/PrimaryCCD.getBinX();
    442431        pd=0.0;
    443         pf=YRes/2/BinY;
     432        pf=PrimaryCCD.getYRes()/2/PrimaryCCD.getBinY();
    444433        //  and we do a simple scale for x and y locations
    445434        //  based on the focal length and pixel size
    446435        //  focal length in mm, pixels in microns
    447         pa=focallength/PixelSizex*1000/BinX;
    448         pe=focallength/PixelSizey*1000/BinY;
     436        pa=focallength/PrimaryCCD.getPixelSizeX()*1000/PrimaryCCD.getBinX();
     437        pe=focallength/PrimaryCCD.getPixelSizeY()*1000/PrimaryCCD.getBinY();
    449438
    450439        //IDLog("Pixels are %4.2f %4.2f  pa %6.4f  pe %6.4f\n",PixelSizex,PixelSizey,pa,pe);
     
    478467        float radius;
    479468
    480         radius=sqrt((Scalex*Scalex*XRes/2.0*XRes/2.0)+(Scaley*Scaley*YRes/2.0*YRes/2.0));
     469        radius=sqrt((Scalex*Scalex*PrimaryCCD.getXRes()/2.0*PrimaryCCD.getXRes()/2.0)+(Scaley*Scaley*PrimaryCCD.getYRes()/2.0*PrimaryCCD.getYRes()/2.0));
    481470        //  we have radius in arcseconds now
    482471        radius=radius/60;   //  convert to arcminutes
     
    505494
    506495        //  if this is a light frame, we need a star field drawn
    507         if(FrameType==FRAME_TYPE_LIGHT)
     496        if(PrimaryCCD.getFrameType()==CCDChip::LIGHT_FRAME)
    508497        {
    509498            //sprintf(gsccmd,"gsc -c %8.6f %+8.6f -r 120 -m 0 9.1",rad+PEOffset,Dec);
     
    593582        //  fwhm equivalent to the full field of view
    594583
    595         if((FrameType==FRAME_TYPE_LIGHT)||(FrameType==FRAME_TYPE_FLAT))
     584        CCDChip::CCD_FRAME ftype = PrimaryCCD.getFrameType();
     585
     586        if((ftype==CCDChip::LIGHT_FRAME)||(ftype==CCDChip::FLAT_FRAME))
    596587        {
    597588            float skyflux;
     
    599590            //  calculate flux from our zero point and gain values
    600591            glow=skyglow;
    601             if(FrameType==FRAME_TYPE_FLAT)
     592            if(ftype==CCDChip::FLAT_FRAME)
    602593            {
    603594                //  Assume flats are done with a diffuser
     
    610601            //  ok, flux represents one second now
    611602            //  scale up linearly for exposure time
    612             skyflux=skyflux*ExposureRequest*BinX*BinY;
     603            skyflux=skyflux*ExposureRequest*PrimaryCCD.getBinX()*PrimaryCCD.getBinY();
    613604            //IDLog("SkyFlux = %4.2f ExposureRequest %4.2f\n",skyflux,ExposureRequest);
    614605
    615606            unsigned short *pt;
    616             pt=(unsigned short int *)RawFrame;
    617             for(int y=0; y<YRes/BinY; y++) {
    618                 for(int x=0; x<XRes/BinX; x++) {
     607
     608            int nwidth  = PrimaryCCD.getXRes()/PrimaryCCD.getBinX();
     609            int nheight = PrimaryCCD.getYRes()/PrimaryCCD.getBinY();
     610            pt=(unsigned short int *)PrimaryCCD.getFrameBuffer();
     611            for(int y=0; y< nheight; y++) {
     612                for(int x=0; x< nwidth; x++) {
    619613                    float dc;   //  distance from center
    620614                    float fp;   //  flux this pixel;
     
    622616                    float vig;
    623617
    624                     sx=XRes/2/BinX;
     618                    sx=PrimaryCCD.getXRes()/2/PrimaryCCD.getBinX();
    625619                    sx=sx-x;
    626                     sy=YRes/2/BinY;
     620                    sy=PrimaryCCD.getYRes()/2/PrimaryCCD.getBinY();
    627621                    sy=sy-y;
    628622
    629                     vig=XRes/BinX;
     623                    vig=PrimaryCCD.getXRes()/PrimaryCCD.getBinX();
    630624                    vig=vig*ImageScalex;
    631625                    //  need to make this account for actual pixel size
     
    654648
    655649        //  Now we add some bias and read noise
    656         for(x=0; x<XRes; x++) {
    657             for(y=0; y<YRes; y++) {
     650        for(x=0; x<PrimaryCCD.getXRes(); x++) {
     651            for(y=0; y<PrimaryCCD.getYRes(); y++) {
    658652                int noise;
    659653
     
    671665        val=testvalue;
    672666
    673         for(int x=0; x<XRes*YRes; x++)
     667        int nbuf    = PrimaryCCD.getXRes()*PrimaryCCD.getYRes();
     668
     669        for(int x=0; x<nbuf; x++)
    674670        {
    675671            *ptr=val++;
     
    686682    unsigned char val;
    687683
    688     ptr=(unsigned char *)RawGuiderFrame;
     684    ptr=(unsigned char *) GuideCCD.getFrameBuffer();
    689685    testvalue++;
    690686    if(testvalue > 255) testvalue=0;
    691687    val=testvalue;
    692688
    693     for(int x=0; x<GXRes*GYRes; x++) {
     689    int nbuf = GuideCCD.getXRes()*GuideCCD.getYRes();
     690    for(int x=0; x< nbuf; x++)
     691    {
    694692        *ptr=val++;
    695693        ptr++;
     
    708706    float flux;
    709707
    710     if((x<0)||(x>XRes/BinX)||(y<0)||(y>YRes/BinY))
     708    if((x<0)||(x>PrimaryCCD.getXRes()/PrimaryCCD.getBinX())||(y<0)||(y>PrimaryCCD.getYRes()/PrimaryCCD.getBinY()))
    711709    {
    712710        //  this star is not on the ccd frame anyways
     
    750748            float fa;
    751749            fa=exp(-2.0*0.7*(dc*dc)/seeing/seeing);
    752             fp=fa*flux*BinX*BinY;
     750            fp=fa*flux*PrimaryCCD.getBinX()*PrimaryCCD.getBinY();
    753751            if(fp < 0) fp=0;
    754752
     
    773771    int drew=0;
    774772    if(x >= 0) {
    775         if(x < XRes/BinX) {
     773        if(x < PrimaryCCD.getXRes()/PrimaryCCD.getBinX()) {
    776774            if(y >= 0) {
    777                 if(y < YRes/BinY) {
     775                if(y < PrimaryCCD.getYRes()/PrimaryCCD.getBinY()) {
    778776                    unsigned short *pt;
    779777                    int newval;
    780778                    drew++;
    781                     pt=(unsigned short int *)RawFrame;
    782                     pt+=(y*XRes/BinX);
     779                    pt=(unsigned short int *)PrimaryCCD.getFrameBuffer();
     780                    pt+=(y*PrimaryCCD.getXRes()/PrimaryCCD.getBinX());
    783781                    pt+=x;
    784782                    newval=pt[0];
     
    793791}
    794792
    795 int CCDSim::GuideNorth(float v)
     793bool CCDSim::GuideNorth(float v)
    796794{
    797795    float c;
     
    801799    Dec=Dec+c;
    802800
    803     return 0;
    804 }
    805 int CCDSim::GuideSouth(float v)
     801    return true;
     802}
     803bool CCDSim::GuideSouth(float v)
    806804{
    807805    float c;
     
    811809    Dec=Dec-c;
    812810
    813     return 0;
    814 }
    815 
    816 int CCDSim::GuideEast(float v)
     811    return true;
     812}
     813
     814bool CCDSim::GuideEast(float v)
    817815{
    818816    float c;
     
    823821    RA=RA-c;
    824822
    825     return 0;
    826 }
    827 int CCDSim::GuideWest(float v)
     823    return true;
     824}
     825bool CCDSim::GuideWest(float v)
    828826{
    829827    float c;
     
    834832    RA=RA+c;
    835833
    836     return 0;
    837 }
    838 
    839 void CCDSim::ISSnoopDevice (XMLEle *root)
    840  {
    841      //fprintf(stderr,"CCDSim handling snoop\n");
    842      if(IUSnoopNumber(root,&EqNV)==0) {
    843         float newra,newdec;
    844         newra=EqN[0].value;
    845         newdec=EqN[1].value;
    846         if((newra != RA)||(newdec != Dec)) {
    847             //fprintf(stderr,"RA %4.2f  Dec %4.2f Snooped RA %4.2f  Dec %4.2f\n",RA,Dec,newra,newdec);
    848             RA=newra;
    849             Dec=newdec;
    850 
    851         }
    852      } else {
    853         //fprintf(stderr,"Snoop Failed\n");
    854      }
    855  }
     834    return true;
     835}
    856836
    857837bool CCDSim::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
     
    859839    //  first check if it's for our device
    860840    //IDLog("INDI::CCD::ISNewNumber %s\n",name);
    861     if(strcmp(dev,deviceName())==0) {
     841    if(strcmp(dev,deviceName())==0)
     842    {
    862843        //  This is for our device
    863844        //  Now lets see if it's something we process here
     
    899880    return INDI::CCD::ISNewNumber(dev,name,values,names,n);
    900881}
    901 bool CCDSim::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
    902 {
    903     //  Ok, lets see if this is a property wer process
    904     //IDLog("IndiTelescope got %d new text items name %s\n",n,name);
    905     //  first check if it's for our device
    906     if(strcmp(dev,deviceName())==0) {
    907         //  This is for our device
    908         //  Now lets see if it's something we process here
    909         if(strcmp(name,TelescopeTV->name)==0) {
    910             int rc;
    911             //IDLog("calling update text\n");
    912             TelescopeTV->s=IPS_OK;
    913             rc=IUUpdateText(TelescopeTV,texts,names,n);
    914             //IDLog("update text returns %d\n",rc);
    915             //  Update client display
    916             IDSetText(TelescopeTV,NULL);
    917             saveConfig();
    918             IUFillNumberVector(&EqNV,EqN,2,TelescopeT[0].text,"EQUATORIAL_EOD_COORD","Eq. Coordinates","Main Control",IP_RW,60,IPS_IDLE);
    919             IDSnoopDevice(TelescopeT[0].text,"EQUATORIAL_EOD_COORD");
    920             //  We processed this one, so, tell the world we did it
    921             return true;
    922         }
    923 
    924     }
    925 
    926     return INDI::DefaultDriver::ISNewText(dev,name,texts,names,n);
    927 }
    928882
    929883
  • BAORadio/libindi/libindi/drivers/ccd/ccd_simulator.h

    r504 r642  
    22  Copyright(c) 2010 Gerry Rozema. All rights reserved.
    33
    4   This program is free software; you can redistribute it and/or modify it
    5   under the terms of the GNU General Public License as published by the Free
    6   Software Foundation; either version 2 of the License, or (at your option)
    7   any later version.
    8 
    9   This program is distributed in the hope that it will be useful, but WITHOUT
    10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    12   more details.
    13 
    14   You should have received a copy of the GNU General Public License along with
    15   this program; if not, write to the Free Software Foundation, Inc., 59
    16   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    17 
    18   The full GNU General Public License is included in this distribution in the
    19   file called LICENSE.
     4 This library is free software; you can redistribute it and/or
     5 modify it under the terms of the GNU Library General Public
     6 License version 2 as published by the Free Software Foundation.
     7 .
     8 This library is distributed in the hope that it will be useful,
     9 but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     11 Library General Public License for more details.
     12 .
     13 You should have received a copy of the GNU Library General Public License
     14 along with this library; see the file COPYING.LIB.  If not, write to
     15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     16 Boston, MA 02110-1301, USA.
    2017*******************************************************************************/
    2118
     
    6562        bool AbortGuideFrame;
    6663
    67         float RA;
    68         float Dec;
     64
    6965        float GuideRate;
    7066
     
    7369        time_t RunStart;
    7470
    75         //  We are going to snoop these from a telescope
    76         INumberVectorProperty EqNV;
    77         INumber EqN[2];
    78 
    7971        //  And this lives in our simulator settings page
    8072
    8173        INumberVectorProperty *SimulatorSettingsNV;
    8274        INumber SimulatorSettingsN[13];
    83 
    84         ITextVectorProperty *TelescopeTV; //  A text vector that stores the telescope we want to snoop
    85         IText TelescopeT[1];
    86 
    87         //ISwitch ConfigSaveRestoreS[2];
    88         //ISwitchVectorProperty ConfigSaveRestoreSV;
    8975
    9076        ISwitch TimeFactorS[3];
     
    10389
    10490        void ISGetProperties (const char *dev);
    105         void ISSnoopDevice (XMLEle *root);
    106 
    10791
    10892
     
    123107        int AddToPixel(int,int,int);
    124108
    125         int GuideNorth(float);
    126         int GuideSouth(float);
    127         int GuideEast(float);
    128         int GuideWest(float);
     109        bool GuideNorth(float);
     110        bool GuideSouth(float);
     111        bool GuideEast(float);
     112        bool GuideWest(float);
    129113
    130114        virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
    131         virtual bool ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n);
    132115        virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n);
    133116
  • BAORadio/libindi/libindi/drivers/filter_wheel/filter_simulator.cpp

    r504 r642  
     1/*******************************************************************************
     2  Copyright(c) 2010 Gerry Rozema. All rights reserved.
     3
     4 This library is free software; you can redistribute it and/or
     5 modify it under the terms of the GNU Library General Public
     6 License version 2 as published by the Free Software Foundation.
     7
     8 This library is distributed in the hope that it will be useful,
     9 but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     11 Library General Public License for more details.
     12
     13 You should have received a copy of the GNU Library General Public License
     14 along with this library; see the file COPYING.LIB.  If not, write to
     15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     16 Boston, MA 02110-1301, USA.
     17*******************************************************************************/
     18
    119#include "filter_simulator.h"
    220
     
    90108}
    91109
    92 int FilterSim::SelectFilter(int f)
     110bool FilterSim::SelectFilter(int f)
    93111{
    94112    CurrentFilter=f;
    95113    SetTimer(500);
    96     return 0;
     114    return true;
    97115}
    98116
  • BAORadio/libindi/libindi/drivers/filter_wheel/filter_simulator.h

    r504 r642  
    22  Copyright(c) 2010 Gerry Rozema. All rights reserved.
    33
    4   This program is free software; you can redistribute it and/or modify it
    5   under the terms of the GNU General Public License as published by the Free
    6   Software Foundation; either version 2 of the License, or (at your option)
    7   any later version.
     4 This library is free software; you can redistribute it and/or
     5 modify it under the terms of the GNU Library General Public
     6 License version 2 as published by the Free Software Foundation.
    87
    9   This program is distributed in the hope that it will be useful, but WITHOUT
    10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    12   more details.
     8 This library is distributed in the hope that it will be useful,
     9 but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     11 Library General Public License for more details.
    1312
    14   You should have received a copy of the GNU General Public License along with
    15   this program; if not, write to the Free Software Foundation, Inc., 59
    16   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    17 
    18   The full GNU General Public License is included in this distribution in the
    19   file called LICENSE.
     13 You should have received a copy of the GNU Library General Public License
     14 along with this library; see the file COPYING.LIB.  If not, write to
     15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     16 Boston, MA 02110-1301, USA.
    2017*******************************************************************************/
    2118
     
    3734        bool Connect();
    3835        bool Disconnect();
    39         int SelectFilter(int);
     36        bool SelectFilter(int);
    4037        void TimerHit();
     38
     39        virtual bool SetFilterNames() { return false; }
     40        virtual bool GetFilterNames(const char *deviceName, const char* groupName) { return false; }
     41
    4142
    4243};
  • BAORadio/libindi/libindi/drivers/focuser/tcfs.cpp

    r504 r642  
    8282        if(dev && strcmp (mydev, dev)) return;
    8383        ISInit();
    84         tcfs->ISNewSwitch(name, states, names, num);
     84        tcfs->ISNewSwitch(dev, name, states, names, num);
    8585}
    8686
     
    8989        if(dev && strcmp (mydev, dev)) return;
    9090        ISInit();
    91         tcfs->ISNewText(name, texts, names, num);
     91        tcfs->ISNewText(dev, name, texts, names, num);
    9292}
    9393
     
    9696        if(dev && strcmp (mydev, dev)) return;
    9797        ISInit();
    98         tcfs->ISNewNumber(name, values, names, num);
     98        tcfs->ISNewNumber(dev, name, values, names, num);
    9999}
    100100
     
    239239    if (tty_connect(tProp->tp[0].text, 19200, 8, 0, 1, &fd) != TTY_OK)
    240240    {
    241         ConnectSP->s = IPS_ALERT;
    242         IDSetSwitch (ConnectSP, "Error connecting to port %s. Make sure you have BOTH read and write permission to the port.", tProp->tp[0].text);
     241        IDMessage(deviceName(), "Error connecting to port %s. Make sure you have BOTH read and write permission to the port.", tProp->tp[0].text);
    243242        return false;
    244243    }
     
    252251            if (!strcmp(response, "!"))
    253252            {
    254                 setConnected(true, IPS_OK, "Successfully connected to TCF-S Focuser in Manual Mode.");
     253                IDMessage(deviceName(), "Successfully connected to TCF-S Focuser in Manual Mode.");
    255254
    256255                IUResetSwitch(FocusModeSP);
     
    275274    }
    276275
    277     setConnected(false, IPS_ALERT, "Error connecting to TCF-S focuser...");
     276    IDMessage(deviceName(), "Error connecting to TCF-S focuser...");
    278277    return false;
    279278
     
    306305**
    307306*****************************************************************/
    308 bool TCFS::ISNewNumber (const char *name, double values[], char *names[], int n)
     307bool TCFS::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
    309308{
    310309
     
    317316  {
    318317      resetProperties();
    319       IDMessage(deviceID, "TCF-S is offline. Connect before issiung any commands.");
     318      IDMessage(deviceName(), "TCF-S is offline. Connect before issiung any commands.");
    320319      return false;
    321320  }
     
    355354      return true;
    356355  }
     356
     357  return DefaultDriver::ISNewNumber (dev, name, values, names, n);
    357358   
    358359}
     
    362363**
    363364*****************************************************************/
    364 bool TCFS::ISNewText (const char *name, char *texts[], char *names[], int n)
     365bool TCFS::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
    365366{
    366367    ITextVectorProperty * tProp = getText(name);
     
    382383
    383384
    384     return false;
     385    return DefaultDriver::ISNewText(dev, name, texts, names, n);
    385386       
    386387}
     
    390391**
    391392*****************************************************************/
    392 bool TCFS::ISNewSwitch (const char *name, ISState *states, char *names[], int n)
     393bool TCFS::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
    393394{
    394395
    395396    ISwitch *current_active_switch = NULL, *target_active_switch = NULL;
    396397    // First process parent!
    397     if (INDI::DefaultDriver::ISNewSwitch(deviceID, name, states, names, n) == true)
     398    if (INDI::DefaultDriver::ISNewSwitch(deviceName(), name, states, names, n) == true)
    398399        return true;
    399400
     
    416417    {
    417418      resetProperties();
    418       IDMessage(deviceID, "TCF-S is offline. Connect before issiung any commands.");
     419      IDMessage(deviceName(), "TCF-S is offline. Connect before issiung any commands.");
    419420      return false;
    420421    }
     
    663664
    664665
    665     return false;
     666    return DefaultDriver::ISNewSwitch(dev, name, states, names, n);
    666667}
    667668
     
    930931const char * TCFS::getDefaultName()
    931932{
    932     return "TCFS";
    933 }
     933    return mydev;
     934}
  • BAORadio/libindi/libindi/drivers/focuser/tcfs.h

    r504 r642  
    6666    // Standard INDI interface fucntions
    6767    virtual void ISGetProperties(const char *dev);
    68     virtual bool ISNewNumber (const char *name, double values[], char *names[], int n);
    69     virtual bool ISNewText (const char *name, char *texts[], char *names[], int n);
    70     virtual bool ISNewSwitch (const char *name, ISState *states, char *names[], int n);
     68    virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
     69    virtual bool ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n);
     70    virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n);
    7171       
    7272
  • BAORadio/libindi/libindi/drivers/telescope/BAO.cpp

    r619 r642  
    1111
    1212#include "BAO.h"
     13#include "../communs/alt2motor.h"
    1314
    1415
     
    2223const char *OPTIONS_GROUP  = "Options";                 // Options Group
    2324
    24 /* Handy Macros */
    25 //#define currentRA     EquatorialCoordsRN[0].value
    26 //#define currentDEC    EquatorialCoordsRN[1].value
    27 #define targetRA        EquatorialCoordsWN[0].value
    28 #define targetDEC       EquatorialCoordsWN[1].value
     25
     26#define targetRA    EquatorialCoordsWN[0].value
     27#define targetDEC   EquatorialCoordsWN[1].value
    2928
    3029
     
    3433
    3534
     35
    3636/**************************************************************************************
    3737** Initialisation de la classe BAO
     38**
    3839***************************************************************************************/
    3940
     
    4243    init_properties();
    4344
    44     // télescope en état IDLE
    45     ConnectSP.s    = IPS_IDLE;
     45    // Le bouton connect de la boîte de dialogue d'indi8BAO
     46    // est dans l'état IDLE au démarrage
     47
     48    ConnectSP.s           = IPS_IDLE;
    4649
    4750    // derniÚre actualisation
    48     lastRA         = 0.0;
    49     lastDEC        = 0.0;
    50     JJAnc          = 0.0;
    51 
    52     currentSet     =  0;
    53     lastSet        = -1;
    54     SocketsNumber  =  1;
    55     TrackingMode   =  1;
    56 
    57     // délais en sec entre deux actualisations de la
    58     // position dans les modes transit et tracking
    59 
    60     ActualisationTM1 = 15.0 * 60.0;
    61     ActualisationTM2 = 5.0;
    62 
    63     UpdateGoto      = true;
    64     InitThreadOK    = false;
    65     ActualisationPosition = false;
    66     Abort           = false;
    67     Park            = false;
    68     Suivi           = false;
    69     Exit            = false;
     51
     52    lastRA                = 0.0;
     53    lastDEC               = 0.0;
     54    JJAnc                 = 0.0;
     55
     56    // Variables d'état
     57
     58    currentSet            =  0;         // Variables internes d'Indi, ne pas toucher
     59    lastSet               = -1;         // Variable interne d'Indi, ne pas toucher
     60
     61    // Nombre d'antennes connectées
     62
     63    SocketsNumber         =  1;
     64
     65    // Le mode tracking est activé par défaut
     66
     67    TrackingMode          =  1;
     68
     69    // délais en sec entre deux actualisations
     70    // dans les modes transit et tracking
     71
     72    ActualisationTMTransit  = 15.0 * 60.0;    // Délai entre 2 actualisations dans le mode transit
     73    ActualisationTMTracking = 5.0;            //                "                 "        tracking
     74
     75    // cette variable vaut "true" lorsque le thread de l'aplication a été initialisé
     76
     77    InitThreadOK          = false;
     78
     79    // UpdatedGoto = true lorsque le dernier goto a bien été réalisé jusqu'au bout
     80
     81    UpdatedGoto           = true;
     82
     83    // RealisationGoto = true lorsque les étapes nécessaires à la réalisation d'un goto
     84    // sont en cours d'execution
     85
     86    RealisationGoto       = false;
     87
     88    // vaut true si l'utilisateur demande l'annulation du mouvement en cours
     89
     90    Abort                 = false;
     91
     92    // vaut true si l'utilisateur demande de mettre les antennes en mode park
     93
     94    Park                  = false;
     95
     96    // vaut true un objet est actuellement suivi par les antennes
     97
     98    Suivi                 = false;
     99
     100    // vaut true si l'utilisateur demande à sortir de l'application -> permet de fermer le thread
     101
     102    Exit                  = false;
     103   
     104    Pression              = 1013.0;
     105   
     106    Temp                  = 10.0;
    70107
    71108
    72109    // initialisation des sockets (Antennes)
    73    
     110
    74111    for (int i=0; i<MAXHOSTNAME; i++)
    75112    {
    76         Sockets[i].Connected = false;
    77         Sockets[i].IP = "";
    78                
    79         Sockets[i].Delta.x = 0.0;
    80         Sockets[i].Delta.y = 0.0;
     113        Sockets[i].Connected         = false;
     114        Sockets[i].IP                = "";
     115        Sockets[i].TargetPosition.x  = 0.0;
     116        Sockets[i].TargetPosition.y  = 0.0;
     117        Sockets[i].AlignementAntenne = new Alignement();
     118
     119        if (Sockets[i].AlignementAntenne) Sockets[i].AlignementAntenne->InitAlignement();
    81120    }
    82121
    83122    // initialisations supplémentaires
    84    
     123
    85124    InitAntennes();
    86125
    87126    // Numéro de version
    88    
    89     IDLog("Initilizing from BAO device...\n");
    90     IDLog("Driver Version: 2011-12-02\n");
     127
     128    IDLog("Indi server BAORadio...\n");
     129    IDLog("Driver Version: 23-02-2012\n");
    91130
    92131    //connect_telescope();
     
    94133
    95134
     135
    96136/**************************************************************************************
    97137** Destructeur
    98 ** Lorsque l'on lance indi_BAO depuis indiserver dans un terminal
    99 ** Le destructeur ne semble jamais être atteint lorsque l'on sort... A vérifier
    100 ***************************************************************************************/
     138**
     139***************************************************************************************/
     140
    101141BAO::~BAO()
    102142{
     143    //On informe le thread que nous allons sortir
     144
    103145    Exit = true;
     146
     147    // On lui laisse une seconde pour qu'il se termine
     148
    104149    sleep(1);
    105     pthread_join (th1, NULL);
    106 }
     150
     151    // destruction du thread
     152
     153    pthread_join(th1, NULL);
     154
     155    // destruction des objets AlignementAntennes
     156
     157    for (int i=0; i<MAXHOSTNAME; i++)
     158    {
     159        delete Sockets[i].AlignementAntenne;
     160    }
     161
     162    // Petit message à l'attention de l'utilisateur
     163    // permet de savoir si le destructeur est bien atteint
     164
     165    IDLog("Sortie de indi_BAO\n");
     166}
     167
    107168
    108169
    109170/************************************************************************************
    110 * Initialisation des paramÚtres des antennes
    111 *
     171** Initialisation des paramÚtres des antennes
     172**
    112173************************************************************************************/
     174
    113175void BAO::InitAntennes()
    114176{
     
    121183        Sockets[i].etape              = 0;
    122184
    123         Sockets[i].ack_status = false;
    124         Sockets[i].ack_pos    = false;
    125         Sockets[i].ack_park   = false;
    126         Sockets[i].ack_abort  = false;
    127         Sockets[i].ack_goto   = false;
    128 
    129         Sockets[i].PosValides = false;
    130         Sockets[i].GotoOk     = false;
    131     }
    132 }
     185        Sockets[i].ack_status         = false;
     186        Sockets[i].ack_pos            = false;
     187        Sockets[i].ack_park           = false;
     188        Sockets[i].ack_abort          = false;
     189        Sockets[i].ack_goto           = false;
     190
     191        Sockets[i].PosValides         = false;
     192        Sockets[i].GotoOk             = false;
     193    }
     194}
     195
    133196
    134197
    135198/**************************************************************************************
    136199** Initialisation des boutons et des zones d'affichage dans la boîte de dialogue INDI
     200** se référer à la documentation d'INDI
     201**
    137202***************************************************************************************/
    138203
     
    149214    IUFillSwitchVector(&OnCoordSetSP, OnCoordSetS, NARRAY(OnCoordSetS), mydev, "ON_COORD_SET", "On Set", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
    150215
     216    // Alignment Set
     217    IUFillSwitch(&AlignmentS[0], "SIMPLE", "Simple", ISS_ON);
     218    IUFillSwitch(&AlignmentS[1], "AFFINE", "Affine", ISS_OFF);
     219    IUFillSwitch(&AlignmentS[2], "TAKI", "Taki", ISS_OFF);
     220    IUFillSwitchVector(&AlignmentSP, AlignmentS, NARRAY(AlignmentS), mydev, "ALIGNMENT_SET", "Alignment", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
     221
    151222    // Abort
    152223    IUFillSwitch(&AbortSlewS[0], "ABORT", "Abort", ISS_OFF);
     
    171242    IUFillNumberVector(&GeographicCoordsWNP, GeographicCoordsWN, NARRAY(GeographicCoordsWN), mydev, "GEOGRAPHIC_COORD" , "Geographic coords", OPTIONS_GROUP, IP_WO, 0, IPS_IDLE);
    172243
     244     // Pression température - SET
     245    IUFillNumber(&PressionTempWN[0], "Pression", "Pression mb", "%10.6m",  0., 1500., 0., 0.);
     246    IUFillNumber(&PressionTempWN[1], "Temperature", "Temperature °c", "%10.6m", -50., +50., 0., 0.);
     247    IUFillNumberVector(&PressionTempWNP, PressionTempWN, NARRAY(PressionTempWN), mydev, "PRESSION_DATA" , "Pression, Temperature", OPTIONS_GROUP, IP_WO, 0, IPS_IDLE);
     248
    173249    // Actualisation - SET
    174     IUFillNumber(&ActualisationN1[0], "DELAY", "Transit mode delay (Sec)", "%10.6m",  0., 3600., 0., 0.);
     250    IUFillNumber(&ActualisationN1[0], "DELAY", "Transit delay (s)", "%10.6m",  0., 3600., 0., 0.);
    175251    IUFillNumberVector(&ActualisationNP1, ActualisationN1, NARRAY(ActualisationN1), mydev, "DELAY1" , "", OPTIONS_GROUP, IP_WO, 0, IPS_IDLE);
    176252
    177     IUFillNumber(&ActualisationN2[0], "DELAY", "Tracking mode delay (Sec)", "%10.6m",  0., 3600., 0., 0.);
     253    IUFillNumber(&ActualisationN2[0], "DELAY", "Tracking delay (s)", "%10.6m",  0., 3600., 0., 0.);
    178254    IUFillNumberVector(&ActualisationNP2, ActualisationN2, NARRAY(ActualisationN2), mydev, "DELAY2" , "", OPTIONS_GROUP, IP_WO, 0, IPS_IDLE);
    179255}
     
    182258/**************************************************************************************
    183259** Initialisation de la boîte de dialogue INDI (suite)
     260** Vider tous les vecteurs
     261**
    184262***************************************************************************************/
    185263
     
    195273    IDDefNumber(&EquatorialCoordsWNP, NULL);
    196274    IDDefNumber(&GeographicCoordsWNP, NULL);
     275    IDDefNumber(&PressionTempWNP, NULL);
    197276    IDDefSwitch(&OnCoordSetSP, NULL);
     277    IDDefSwitch(&AlignmentSP, NULL);
    198278    IDDefSwitch(&AbortSlewSP, NULL);
    199279    IDDefSwitch(&ParkSP, NULL);
     
    207287/**************************************************************************************
    208288** Initialisation des vecteurs INDI
     289** ParamÚtres par défaut
     290**
    209291***************************************************************************************/
    210292
     
    213295    ConnectSP.s                 = IPS_IDLE;
    214296    OnCoordSetSP.s              = IPS_IDLE;
     297    AlignmentSP.s               = IPS_IDLE;
    215298    AbortSlewSP.s               = IPS_IDLE;
    216299    ParkSP.s                    = IPS_IDLE;
    217300    ObjectTP.s                  = IPS_IDLE;
    218301    EquatorialCoordsWNP.s       = IPS_IDLE;
     302    PressionTempWNP.s           = IPS_IDLE;
    219303    GeographicCoordsWNP.s       = IPS_IDLE;
    220304    ActualisationNP1.s          = IPS_IDLE;
     
    222306
    223307    IUResetSwitch(&OnCoordSetSP);
     308    IUResetSwitch(&AlignmentSP);
    224309    IUResetSwitch(&AbortSlewSP);
    225310    IUResetSwitch(&ParkSP);
    226311
    227312    OnCoordSetS[0].s = ISS_ON;
     313    AlignmentS[0].s = ISS_ON;
    228314    ConnectS[0].s = ISS_OFF;
    229315    ConnectS[1].s = ISS_ON;
     
    231317    IDSetSwitch(&ConnectSP, NULL);
    232318    IDSetSwitch(&OnCoordSetSP, NULL);
     319    IDSetSwitch(&AlignmentSP, NULL);
    233320    IDSetSwitch(&AbortSlewSP, NULL);
    234321    IDSetSwitch(&ParkSP, NULL);
    235322    IDSetText(&ObjectTP, NULL);
    236323    IDSetNumber(&EquatorialCoordsWNP, NULL);
     324    IDSetNumber(&PressionTempWNP, NULL);
    237325    IDSetNumber(&GeographicCoordsWNP, NULL);
    238326    IDSetNumber(&ActualisationNP1, NULL);
     
    241329
    242330
     331
    243332/**************************************************************************************
    244333** En cas de changement de texte dans la boîte de dialogue (par exemple : changement du
    245 ** nom de l'objet) alors suivre l'objet... 
     334** nom de l'objet) alors suivre l'objet...
    246335** Cette fonction n'est pas encore utilisée
     336** TODO: faut-il pouvoir modifier le nom de l'objet depuis la boîte ?
     337** pas sûr que cela soit utile: kstars et BAOcontrol permettent de faire cela
     338**
    247339***************************************************************************************/
    248340
     
    275367
    276368
     369
    277370/**************************************************************************************
    278371** En cas de changement d'une valeur numérique dans la boîte de dialogue Indi
     
    285378
    286379    // Ignore if not ours
     380
    287381    if (strcmp (dev, mydev))
    288382        return;
    289383
     384    // Si pas de connexion -> on sort
     385
    290386    if (is_connected() == false)
    291387    {
    292388        IDMessage(mydev, "Error ! BAO is offline. Please connect before issuing any commands.");
     389
    293390        reset_all_properties();
     391
    294392        return;
    295393    }
     
    299397    // Geographic  Coords
    300398    // ===================================
     399
    301400    if (!strcmp (name, GeographicCoordsWNP.name))
    302401    {
    303         int i=0, nset=0, error_code=0;
    304 
    305         Latitude=0.0;
    306         Longitude=0.0;
    307 
    308         for (nset = i = 0; i < n; i++)
    309         {
     402        // l'utilisateur a modifié un les coordonnées géographiques de la boite indi
     403
     404        int i = 0, nset = 0;
     405
     406        // En cas d'erreur, on doit pouvoir sortir avec des paramÚtres par défaut
     407        //ici la latitude et la longitude vondront 0.0
     408
     409        Latitude  = 0.0;
     410        Longitude = 0.0;
     411
     412        // pour ce vecteur, on sait qu'il y a n éléments possibles
     413        // Exemple pour la rubrique coordonnées géographique de la boîte indi
     414        // il y a deux éléments : la longtude et la latitude
     415        // pour la rubrique alignement, il y aen a trois par exemple :
     416        // simple, affine et taki
     417
     418        for (i = 0; i < n; i++)
     419        {
     420            // pour chacun d'entre eux, on regarde si le nom passé en argument de la fonction (*name)
     421            // correspond bien à l'un des éléments du vecteur GeographicCoordsWNP
     422
    310423            INumber *eqp = IUFindNumber (&GeographicCoordsWNP, names[i]);
     424
    311425            if (eqp == &GeographicCoordsWN[0])
    312426            {
     427                //ici on a identifié la zone latitude de la boîte de dialogue
     428                // Value[i] contient la chaine de caractÚre correspondante dans la boîte
     429                // C'est la valeur saisie par l'utilisateur
     430
    313431                Latitude = values[i];
     432
     433                // On doit vérifier que la latitude est dans un intervalle correct
     434
    314435                nset += Latitude >= -90.0 && Latitude <= 90.0;
     436
     437                // on convertit en radians
    315438
    316439                Latitude *= Pidiv180;
     
    318441            else if (eqp == &GeographicCoordsWN[1])
    319442            {
     443                // ici on a identifié une modification dans la rubrique longitude
     444
    320445                Longitude = values[i];
     446
     447                // dans l'intervalle ?
     448
    321449                nset += Longitude >= 0.0 && Longitude <= 360.0;
     450
     451                // en radians
    322452
    323453                Longitude *= -Pidiv180;
     
    332462            //IDLog("Geographic : RA %5.2f - DEC %5.2f\n", Latitude, Longitude);
    333463
     464            //nset vaut 2, on sommes donc sûrs qu'il n'y a pas de problÚme dans les valeurs
     465            // saisies par l'utilisateur
     466            // voir le code plus haut pour comprendre...
     467
     468            // On change la couleur de la "diode" de la rubrique coordonnées géographiques de la boîte
     469            // en vert
     470
    334471            GeographicCoordsWNP.s = IPS_OK;
     472
     473            // pas de message d'erreur dans la boîte
     474
    335475            IDSetNumber(&GeographicCoordsWNP, NULL);
    336476        }
    337477        else
    338478        {
     479            // quelque chose cloche
     480            // peut-être l'une des veleurs saisies par l'utilisateur n'est-elle pas dans
     481            // le bon intervalle ? ex : lat = 150°
     482
     483            // on change la couleur de la diode
     484
    339485            GeographicCoordsWNP.s = IPS_ALERT;
     486
     487            // on affiche un message d'erreur
     488
    340489            IDSetNumber(&GeographicCoordsWNP, "Latitude or Longitude missing or invalid");
    341490
    342             Latitude=0.0;
    343             Longitude=0.0;
    344         }
     491            // on fixe arbitrairement les valeurs à 0
     492
     493            Latitude  = 0.0;
     494            Longitude = 0.0;
     495        }
     496
     497        // c'est bon. On peut donc transmettre les nouvelles valeurs à la classe astro
     498        // qui utilisera ces informations pur calculer l'azimut des objets et le tsl en particulier...
    345499
    346500        DefinirLongitudeLatitude(Longitude, Latitude);
     
    355509    if (!strcmp (name, EquatorialCoordsWNP.name))
    356510    {
    357         int i=0, nset=0, error_code=0;
    358         double newRA =0, newDEC =0;
    359 
    360         for (nset = i = 0; i < n; i++)
     511        int i = 0, nset = 0;
     512
     513        double newRA =0.0, newDEC =0.0;
     514
     515        // nous avons le même principe de fonctionnement que pour les coordonnées géographiques
     516
     517        for (i = 0; i < n; i++)
    361518        {
    362519            INumber *eqp = IUFindNumber (&EquatorialCoordsWNP, names[i]);
     520
    363521            if (eqp == &EquatorialCoordsWN[0])
    364522            {
     523                // on a compris que l'utilisateur avait changé l'ascension droite de l'objet
     524
     525                // on affecte la nouvelle valeur à newRA
     526
    365527                newRA = values[i];
     528
     529                // Est-ce que cette valeur est dans le bon intervalle ?
     530
    366531                nset += newRA >= 0 && newRA <= 24.0;
    367532            }
    368533            else if (eqp == &EquatorialCoordsWN[1])
    369534            {
     535                //même chose pour la déclinaison
    370536                newDEC = values[i];
     537
    371538                nset += newDEC >= -90.0 && newDEC <= 90.0;
    372539            }
     
    375542
    376543        // si les coordonnées de l'objet sont correctes
     544
    377545        if (nset == 2)
    378546        {
     
    380548            double targetAZ, targetAlt;
    381549
     550            // On garde une trace des nouvelles coordonnées saisies par l'utilisateur
     551
    382552            targetRA  = newRA;
    383553            targetDEC = newDEC;
    384554
     555            // on les affiches dans les logs
     556
    385557            fs_sexa(RAStr, newRA, 2, 3600);
    386558            fs_sexa(DecStr, newDEC, 2, 3600);
     
    392564
    393565            ADDEC2Motor(newRA, newDEC);
     566
     567            // on déclenche le goto
    394568
    395569            if (process_coords() == false)
    396570            {
    397571                EquatorialCoordsWNP.s = IPS_ALERT;
     572
    398573                IDSetNumber(&EquatorialCoordsWNP, NULL);
    399574            }
     
    402577        {
    403578            EquatorialCoordsWNP.s = IPS_ALERT;
     579
    404580            IDSetNumber(&EquatorialCoordsWNP, "Error ! RA or Dec missing or invalid");
    405581        }
     
    407583        return;
    408584    }
     585   
     586   
     587    // ===================================
     588    // Pression, Temperature
     589    // ===================================
     590    if (!strcmp (name, PressionTempWNP.name))
     591    {
     592        int i = 0, nset = 0;
     593
     594        double newPression =0.0, newTemperature =0.0;
     595
     596        // nous avons le même principe de fonctionnement que pour les coordonnées géographiques
     597
     598        for (i = 0; i < n; i++)
     599        {
     600            INumber *eqp = IUFindNumber (&PressionTempWNP, names[i]);
     601
     602            if (eqp == &PressionTempWN[0])
     603            {
     604                // on a compris que l'utilisateur avait changé l'ascension droite de l'objet
     605
     606                // on affecte la nouvelle valeur à newRA
     607
     608                newPression = values[i];
     609
     610                // Est-ce que cette valeur est dans le bon intervalle ?
     611
     612                nset += newPression >= 0.0 && newPression <= 1500.0;
     613            }
     614            else if (eqp == &PressionTempWN[1])
     615            {
     616                //même chose pour la déclinaison
     617                newTemperature = values[i];
     618
     619                nset += newTemperature >= -50.0 && newTemperature <= 50.0;
     620            }
     621        }
     622
     623
     624        // si les coordonnées de l'objet sont correctes
     625
     626        if (nset == 2)
     627        { 
     628            PressionTempWNP.s = IPS_OK;
     629
     630            IDSetNumber(&PressionTempWNP, NULL);
     631                   
     632            Pression = newPression;
     633            Temp = newTemperature;
     634        }
     635        else
     636        {
     637            PressionTempWNP.s = IPS_ALERT;
     638
     639            IDSetNumber(&PressionTempWNP, "Error ! Bad values for pression or temperature");
     640        }
     641
     642        return;
     643    }
     644
    409645
    410646    // ===================================
     
    413649    if (!strcmp (name, ActualisationNP1.name))
    414650    {
    415         int i=0, nset=0, error_code=0;
    416         double newAct1 =0;
    417 
    418         for (nset = i = 0; i < n; i++)
     651        // on a ici exactement le même fonctionnement que précédement
     652        // on régle ici les valeurs des delais entre deux actualisations
     653        // de la position en mode transit et tracking
     654        // retourne un message d'erreur si les durées ne sont pas exprimées
     655        // dans un intervalle > 0.0 et < 3600
     656
     657        double newAct1 = 1.0;
     658
     659        for (int i = 0; i < n; i++)
    419660        {
    420661            INumber *eqp = IUFindNumber (&ActualisationNP1, names[i]);
     662
    421663            if (eqp == &ActualisationN1[0])
    422664            {
    423665                newAct1 = values[i];
    424666
    425                 if (newAct1 >= 0.0 && newAct1 <= 3600.0)
     667                if ( newAct1 >= 0.0 && newAct1 <= 3600.0 )
    426668                {
    427                     ActualisationTM1 = newAct1;
     669                    ActualisationTMTransit = newAct1;
    428670
    429671                    ActualisationNP1.s = IPS_OK;
     672
    430673                    IDSetNumber(&ActualisationNP1, NULL);
    431674                }
     
    433676                {
    434677                    ActualisationNP1.s = IPS_ALERT;
     678
    435679                    IDSetNumber(&ActualisationNP1, "Error ! Delay invalid");
    436680                }
     
    441685    if (!strcmp (name, ActualisationNP2.name))
    442686    {
    443         int i=0, nset=0, error_code=0;
    444         double newAct2 =0;
    445 
    446         for (nset = i = 0; i < n; i++)
     687        double newAct2 = 1.0;
     688
     689        for (int i = 0; i < n; i++)
    447690        {
    448691            INumber *eqp = IUFindNumber (&ActualisationNP2, names[i]);
     692
    449693            if (eqp == &ActualisationN2[0])
    450694            {
    451695                newAct2 = values[i];
    452696
    453                 if (newAct2 >= 0.0 && newAct2 <= 3600.0)
     697                if ( newAct2 >= 0.0 && newAct2 <= 3600.0 )
    454698                {
    455                     ActualisationTM2 = newAct2;
     699                    ActualisationTMTracking = newAct2;
    456700
    457701                    ActualisationNP2.s = IPS_OK;
     702
    458703                    IDSetNumber(&ActualisationNP2, NULL);
    459704                }
     
    469714
    470715
     716
    471717/**************************************************************************************
    472718** L'utilisateur clique sur l'un des boutons de la boîte Indi
     719**
    473720***************************************************************************************/
    474721
     
    513760
    514761    // ===================================
     762    // Alignment Set
     763    // ===================================
     764    if (!strcmp(name, AlignmentSP.name))
     765    {
     766        if (IUUpdateSwitch(&AlignmentSP, states, names, n) < 0)
     767            return;
     768
     769        currentSet = get_switch_index(&AlignmentSP);
     770        AlignmentSP.s = IPS_OK;
     771        IDSetSwitch(&AlignmentSP, NULL);
     772
     773        for (int i=0; i<MAXALIGNEMENTANTENNE; i++)
     774        {
     775            switch (currentSet)
     776            {
     777            case 1 :
     778                Sockets[i].AlignementAntenne->MethodeAlignement = SIMPLE;
     779                break;
     780            case 2 :
     781                Sockets[i].AlignementAntenne->MethodeAlignement = AFFINE;
     782                break;
     783            case 3 :
     784                Sockets[i].AlignementAntenne->MethodeAlignement = TAKI;
     785                break;
     786            }
     787        }
     788
     789        return;
     790    }
     791
     792    // ===================================
    515793    // Abort slew
    516794    // ===================================
    517795    if (!strcmp (name, AbortSlewSP.name))
    518796    {
    519         Abort=true;
     797        Abort = true;
    520798
    521799        IUResetSwitch(&AbortSlewSP);
     
    568846** l'utilisation d'un thread permet de contourner le problÚme de la fonction accept
    569847** qui est bloquante.
     848**
    570849***************************************************************************************/
    571850
     
    590869            IDLog("\n");*/
    591870        }
    592        
    593         sleep(1); // faire une pause pour éviter de consommer trop de temps CPU -> à vérifier 
     871
     872        sleep(1); // faire une pause pour éviter de consommer trop de temps CPU -> à vérifier
    594873    }
    595874    while (!Exit);
     
    617896** Le retour de la commande P est POSITION/valeur_az/valeur_alt/
    618897** ExtractPosition retourne donc Valeur_az et Valeur_alt
     898**
    619899***************************************************************************************/
    620900
     
    633913        if (pos != string::npos)
    634914        {
    635             result->x = atol(str2.substr(0, pos).c_str());
    636 
    637             result->y = atol(str2.substr(pos + 1).c_str());
    638            
    639             return true;
    640         }       
    641     } 
     915            result->x = atol( str2.substr(0, pos).c_str() );
     916
     917            result->y = atol( str2.substr(pos + 1).c_str() );
     918
     919            return true;
     920        }
     921    }
    642922
    643923    IDLog((str +" failed !\n").c_str());
     
    649929
    650930/************************************************************************************
    651 * cette procédure convertit les coordonnées équatoriales de l'objet visé
    652 * en unités de codeurs des paraboles (nb de tours des deux axes moteurs depuis la position PARK)
     931** Cette procédure, aprÚs avoir appliqué la matrice de rotation aux coordonnées
     932** visées par l'utilisateur, convertit les coordonnées équatoriales de l'objet visé
     933** en unités de codeurs des paraboles
     934** (càd en nb de tours des deux axes moteurs depuis la position PARK)
     935**
    653936************************************************************************************/
    654937
     
    657940    double targetAz;
    658941    double targetAlt;
     942    double newRA2  = newRA * 15.0 * Pidiv180;
     943    double newDEC2 = newDEC * Pidiv180;
    659944    char AzStr[32];
    660945    char AltStr[32];
    661 
    662 
    663     // Calcule la hauteur et l'azimut de la zone du ciel pointée (en fonction de la date et du lieu d'observation)
    664 
    665     Azimut( newRA * 15.0 * Pidiv180, newDEC * Pidiv180, &targetAz, &targetAlt);
    666    
    667     // Correction de la réfraction atmosphérique
    668    
    669     targetAlt = RefractionAtmospherique(targetAlt);
    670 
    671     // Petit calcul pour faire en sorte que le sud soit à 0° d'azimut
    672 
    673     targetAz = VerifAngle( targetAz + Pi );
    674 
    675     // On convertit les angles précédents en degrés
    676 
    677     targetAlt *= N180divPi;
    678     targetAz  *= N180divPi;
    679 
    680     // Affichage dans les logs
    681 
    682     fs_sexa(AzStr, targetAz, 2, 3600);
    683     fs_sexa(AltStr, targetAlt, 2, 3600);
    684 
    685     IDLog("Horizontal coords : Az = %s     Alt = %s\n", AzStr, AltStr);
    686 
    687 
    688     //Conversion des deux angles en pas codeurs
    689 
    690     if ( targetAlt < 30.0 )
    691     {
    692         // L'objet est trop bas (<30°). On annule le suivi...
    693 
    694         IDSetSwitch(&OnCoordSetSP, "Erreur ! L objet suivi est situe a moins de 30° au-dessus de l horizon. Goto annule.");
    695 
    696         Suivi = false;
    697 
    698         ActualisationPosition = false;
    699 
    700         InitAntennes();
    701     }
    702     else
    703     {
    704         // Si la hauteur est supérieure à 90°, on doit ajouter 180° à l'azimut et corriger
    705         // la hauteur en appliquant hauteur=180°-hauteur
    706 
    707         if (targetAlt > 90.0)
    708         {
    709             targetAlt = 180.0 - targetAlt;
    710             targetAz += 180.0;
    711         }
    712 
    713         // On applique la formule de Marc pour convertir la hauteur en nombre de pas codeur alt
    714 
    715         double I0 = 81.0;
    716         double I2 = 128279.4 - 129723.4 * sin( (targetAlt - 20.2345) * Pidiv180 );
    717 
    718         double Codalt = (sqrt(I2) - I0) / 0.078947;
    719 
    720 
    721         TargetPosition.y = (int) Arrondi(Codalt);
    722 
    723         //4000 pas pour 360° sur l'axe az
    724 
    725         TargetPosition.x = (int) Arrondi( targetAz * 4000.0 / 360.0);
    726 
    727         IDLog("Nbre de pas codeurs Az = %i        Alt = %i\n", TargetPosition.x, TargetPosition.y);
    728     }
    729 }
    730 
    731 
    732 /**************************************************************************************
    733 ** Le fichier file existe-t-il et n'est-il pas vide ?
    734 **************************************************************************************/
    735 
    736 bool BAO::is_readable( const std::string & file )
    737 {
    738     std::ifstream fichier( file.c_str() );
    739     if (fichier.fail()) return false;
    740    
    741     // sauvegarder la position courante
    742     long pos = fichier.tellg();
    743     // se placer en fin de fichier
    744     fichier.seekg( 0 , std::ios_base::end );
    745     // récupérer la nouvelle position = la taille du fichier
    746     long size = fichier.tellg() ;
    747     // restaurer la position initiale du fichier
    748     fichier.seekg( pos,  std::ios_base::beg ) ;
    749     return size ;
    750 }
    751 
    752 
    753 /**************************************************************************************
    754 ** Chargement des paramÚtres d'alignement des antennes
    755 **************************************************************************************/
    756 
    757 bool BAO::ChargementParametresAlignement(string fileName)
    758 {
    759     string value;
    760    
    761     stringstream os;
    762    
    763     char *delta_az = NULL;
    764    
    765     char *delta_ha = NULL;
    766        
    767     if (!is_readable(fileName)) return false;
    768      
    769     //IDLog("Chargement du fichier d alignement des antennes %s\n", fileName.c_str());
    770      
    771     //Chargement des corrections des antennes
    772    
     946    Coord result, vect;
     947
     948    // Pour toutes les antennes connectées
     949
    773950    for (int i=0; i<SocketsNumber; i++)
    774951    {
     952        // On vérifie qu'elles sont encore connectées
     953
    775954        if (Sockets[i].Connected)
    776955        {
    777             os << "Alignement antenne ip x.x.x." << Sockets[i].IP.substr(Sockets[i].IP.rfind(".")+1);
    778 
    779             value="delta_az";
    780 
    781             if (readINI((char*)os.str().c_str(), (char*)value.c_str(), &delta_az,  (char*)fileName.c_str()))
    782 
    783             value="delta_ha";
    784 
    785             if (readINI((char*)os.str().c_str(), (char*)value.c_str(), &delta_ha,  (char*)fileName.c_str()))
    786 
    787             if (delta_az && delta_ha)
     956            newRA = newRA2;
     957            newDEC = newDEC2;
     958         
     959            // Dans les modes d'alignement AFFINE et TAKI, on applique la matrice de correction
     960            // sur les coordonnées horaires de l'objet visé
     961
     962            // il faut vérifier auparavent que la matrice de rotation est disponible
     963            // pour l'antenne i
     964
     965            if  (Sockets[i].AlignementAntenne->Matrice_ok)
    788966            {
    789                // Si les corrections de l'antenne i ont été modifiées depuis le démarrage du programme
    790                // -> on les applique...
    791                if (Sockets[i].Delta.x != atol(delta_az) || Sockets[i].Delta.y != atol(delta_ha))
    792                {
    793                   Sockets[i].Delta.x = atol(delta_az);
    794 
    795                   Sockets[i].Delta.y = atol(delta_ha);
    796 
    797                   IDLog("Correction antenne ip %s  deltaAz=%i   deltaHa=%i\n", Sockets[i].IP.c_str(), Sockets[i].Delta.x, Sockets[i].Delta.y);
    798                }
     967                // On est bien dans le cas de l'allignement AFFINE ou Taki
     968
     969                if (Sockets[i].AlignementAntenne->MethodeAlignement ==  AFFINE ||
     970                        Sockets[i].AlignementAntenne->MethodeAlignement ==  TAKI)
     971                {
     972                    // On crée un vecteur avec pour coordonnées
     973                    // x = Angle horaire de l'objet visé
     974                    // y = déclainaison de l'objet
     975                    // z = 1.0
     976                    // Voir la documentation pour plus d'explications sur le calcul affine/taki
     977
     978                    vect.x = VerifAngle( newRA2 - GetTSL() );
     979                    vect.y = newDEC2;
     980                    vect.z = 1.0;
     981
     982                    // Message pour l'utilisateur et les logs
     983
     984                    IDLog("Application de la matrice AFFINE/TAKI\nCoordonnees initiales: AD = %s  Dec = %s\n", DHMS(newRA2*N180divPi, true ).c_str(),
     985                          DHMS(newDEC2*N180divPi, false ).c_str());
     986
     987                    // On applique la matrice de transformation
     988
     989                    switch (Sockets[i].AlignementAntenne->MethodeAlignement)
     990                    {
     991                    case AFFINE :
     992                        Sockets[i].AlignementAntenne->AppliquerMatriceCorrectionAffine(&result, vect);
     993                        break;
     994                    case TAKI   :
     995                        Sockets[i].AlignementAntenne->AppliquerMatriceCorrectionTaki( &result, vect);
     996                        break;
     997                    }
     998
     999                    // On récupÚre les nouvelles coordonnées. z ne nous intéresse pas
     1000
     1001                    newRA  = VerifAngle(result.x+GetTSL());
     1002                    newDEC = result.y;
     1003
     1004                    IDLog("Coordonnees finales: AD = %s  Dec = %s\n", DHMS(newRA*N180divPi, true ).c_str(),
     1005                          DHMS(newDEC*N180divPi, false ).c_str());
     1006                }               
    7991007            }
    800 
    801             if (delta_az) {
    802                 delete [] delta_az;
    803                 delta_az=NULL;
     1008            else
     1009            {
     1010                if (Sockets[i].AlignementAntenne->AlignementEnCours)
     1011                {
     1012                    // Si la matrice n'est pas prête, c'est que la procédure d'alignement de l'antenne i n'est pas encore achevée.
     1013                    // On se contente ici d'appliquer des deltas en ascension droite et en déclinaison. Ces deltas sont envoyés de BAOcontrol
     1014                    // au driver indi_BAO par l'intermédiaire du fichier AlignementAntennes.cfg
     1015                    // Consultez la documentation pour comprendre le principe de fonctionnement de l'alignement et de la communication
     1016                    // entre les deux programmes
     1017
     1018                    newRA  = VerifAngle(newRA2  + Sockets[i].AlignementAntenne->delta_ad[Sockets[i].AlignementAntenne->nbrcorrections] * PasDeltaAD);
     1019                    newDEC = newDEC2 + Sockets[i].AlignementAntenne->delta_de[Sockets[i].AlignementAntenne->nbrcorrections] * PasDeltaDe;
     1020
     1021                    IDLog("Alignement en cours.\nDelta RA=%i  delta Dec=%i\n", Sockets[i].AlignementAntenne->delta_ad[Sockets[i].AlignementAntenne->nbrcorrections], Sockets[i].AlignementAntenne->delta_de[Sockets[i].AlignementAntenne->nbrcorrections]);
     1022                    IDLog("Nouvelles Coordonnées AD =%s  Dec = %s\n", DHMS(newRA*N180divPi, true).c_str(), DHMS(newDEC*N180divPi, false).c_str());               
     1023                }
    8041024            }
    805 
    806             if (delta_ha) {
    807                 delete [] delta_ha;
    808                 delta_ha=NULL;
     1025                   IDLog("Nouvelles Coordonnées AD =%s  Dec = %s\n", DHMS(newRA*N180divPi, true).c_str(), DHMS(newDEC*N180divPi, false).c_str());               
     1026
     1027
     1028            // Calcule la hauteur et l'azimut de la zone du ciel pointée (en fonction de la date et du lieu d'observation)
     1029
     1030            Azimut( newRA, newDEC, &targetAz, &targetAlt);
     1031
     1032            // Si la méthode d'alignement est la méthode SIMPLE, alors on doit cette fois-ci appliquer la matrice
     1033            // de correction au coordonnées horizontales et non aux coordonnées horaires comme ce que nous
     1034            // avons vu plus haut
     1035
     1036            if  (Sockets[i].AlignementAntenne->Matrice_ok && Sockets[i].AlignementAntenne->MethodeAlignement == SIMPLE)
     1037            {
     1038                // AprÚs s'être assurer que nous utilisons la méthode SIMPLE et que la matrice de rotation est ok
     1039
     1040                IDLog("Application de la matrice SIMPLE\nCoordonnees initiales: Azi = %s  Haut = %s\n", DHMS(targetAz*N180divPi, false ).c_str(),
     1041                      DHMS(targetAlt*N180divPi, false ).c_str());
     1042
     1043                // On constitue un vecteur vect
     1044                // Les coordonnées du vecteur correspondont à la position
     1045                // d'un point sur une sphÚre de rayon 1
     1046                // avec une latitude = targetAlt et une longitude=targetAz
     1047                // on reconnait bien les formules de passage des coordonnées
     1048                // sphériques aux coordonnées rectangulaires
     1049               
     1050               
     1051
     1052                vect.x = cos(targetAz) * cos(targetAlt);
     1053                vect.y = sin(targetAz) * cos(targetAlt);
     1054                vect.z = sin(targetAlt);
     1055
     1056
     1057                // Application de la matrice SIMPLE
     1058               
     1059                Sockets[i].AlignementAntenne->AppliquerMatriceCorrectionSimple(&result, vect);
     1060
     1061
     1062                // Là on doit repasser des coordonnées rectangulaires
     1063                // aux coordonnées sphériques
     1064
     1065                if (result.x != 0.0)
     1066                {
     1067                    targetAz = atan( result.y / result.x );
     1068                   
     1069                    if (result.x < 0) targetAz+=Pi;
     1070                }
     1071                else targetAz = Pidiv2;
     1072
     1073                targetAz  = VerifAngle(targetAz);
     1074
     1075                targetAlt = asin(result.z);
     1076
     1077
     1078                IDLog("Coordonnees finales: Azi = %s  Haut = %s\n", DHMS(targetAz*N180divPi, false ).c_str(),
     1079                      DHMS(targetAlt*N180divPi, false ).c_str());
    8091080            }
    8101081
    811             os.str("");
    812         }
    813     }
    814    
    815     return true;
    816 }
     1082            // Application du delta en azimut (préalablement réglé sur la polaire)
     1083            // Correspond à la variable AlignementAntenne->delta_az_polar
     1084            // Ne s'applique que pour les alignements AFFINE et TAKI
     1085
     1086            if (Sockets[i].AlignementAntenne->MethodeAlignement != SIMPLE) targetAz += Sockets[i].AlignementAntenne->delta_az_polar * PasDeltaAD;
     1087
     1088            // Correction de la réfraction atmosphérique
     1089
     1090            targetAlt = RefractionAtmospherique(targetAlt);
     1091
     1092            // On ajoute Pi pour que le sud soit à 0° d'azimut
     1093
     1094            targetAz = VerifAngle( targetAz + Pi );
     1095
     1096            // On convertit les angles précédents en degrés
     1097
     1098            targetAlt *= N180divPi;
     1099            targetAz  *= N180divPi;
     1100
     1101            // Affichage dans les logs
     1102
     1103            fs_sexa(AzStr, targetAz, 2, 3600);
     1104            fs_sexa(AltStr, targetAlt, 2, 3600);
     1105
     1106            IDLog("Coordonnees horizontales finales: Azi = %s  Haut= %s\n", AzStr, AltStr);
     1107
     1108
     1109            //Conversion des deux angles en pas codeurs
     1110
     1111            if ( targetAlt < HAUTMIN )
     1112            {
     1113                // L'objet est trop bas ( < 30°). On annule le suivi...
     1114
     1115                IDSetSwitch(&OnCoordSetSP, "Erreur ! L objet suivi est situe a moins de 30 deg au-dessus de l horizon. Goto annule.");
     1116
     1117                Suivi = false;
     1118
     1119                RealisationGoto = false;
     1120
     1121                InitAntennes();
     1122
     1123                return;
     1124            }
     1125            else
     1126            {
     1127                // Si la hauteur est supérieure à 90°, on doit ajouter 180° à l'azimut et corriger
     1128                // la hauteur en appliquant hauteur=180°-hauteur
     1129
     1130                if (targetAlt > 90.0)
     1131                {
     1132                    targetAlt = 180.0 - targetAlt;
     1133                    targetAz += 180.0;
     1134                }
     1135
     1136                // On applique la formule de Marc pour convertir la hauteur en nombre de pas codeur alt
     1137
     1138                Sockets[i].TargetPosition.y = (int) Arrondi( Alt2Motor( targetAlt ) );
     1139
     1140                //4000 pas pour 360° sur l'axe az
     1141
     1142                Sockets[i].TargetPosition.x = (int) Arrondi( targetAz * 4000.0 / 360.0);
     1143               
     1144                // Message de debug
     1145
     1146                IDLog("Nbre de pas codeurs Az = %i        Alt = %i\n", Sockets[i].TargetPosition.x, Sockets[i].TargetPosition.y);
     1147            }
     1148        }
     1149    }
     1150}
     1151
    8171152
    8181153
    8191154/************************************************************************************
    820 * Retourne le nombre d'antennes connectées
    821 * 
     1155* Retourne le nombre d'antennes actuellement connectées
     1156*
    8221157************************************************************************************/
    8231158
     
    8301165    return num;
    8311166}
     1167
    8321168
    8331169
     
    8391175void BAO::DeconnecterSocket(int num)
    8401176{
    841     IDLog("Deconnexion de l antenne : %s\n", Sockets[num].IP.c_str());
     1177    if (Sockets[num].Connected) IDLog("Deconnexion de l antenne : %s\n", Sockets[num].IP.c_str());
    8421178    Sockets[num].new_sock.shutdown();
    8431179    Sockets[num].Connected = false;
    8441180    Sockets[num].IP = "";
    8451181}
     1182
     1183
    8461184
    8471185
     
    8771215        gettimeofday(&tv, &tz);
    8781216
    879         double Annee=(double)(date.tm_year+1900);
    880         double Mois=(double)(date.tm_mon+1);
    881         double Jour=(double)date.tm_mday;
    882         double Heu=(double)date.tm_hour;
    883         double Min=(double)date.tm_min;
    884         double Sec=(double)date.tm_sec+tv.tv_usec/1.0E6;
    885         double UTCP=0.0;//(double)date.tm_isdst;
     1217        double Annee = (double)(date.tm_year + 1900);
     1218        double Mois  = (double)(date.tm_mon + 1);
     1219        double Jour  = (double)date.tm_mday;
     1220        double Heu   = (double)date.tm_hour;
     1221        double Min   = (double)date.tm_min;
     1222        double Sec   = (double)date.tm_sec+tv.tv_usec/1.0E6;
     1223        double UTCP  = 0.0;//(double)date.tm_isdst;
    8861224
    8871225        // On transmet la date et l'heure à la classe Astro
     
    8921230
    8931231        CalculTSL();
    894     }
    895    
    896     // On chargement les paramÚtres de corrections des antennes toutes les secondes
    897    
    898     if ( compt%1000 == 0 ) ChargementParametresAlignement("/home/" + (string)getenv("USER") + "/AlignementAntennes.cfg");
     1232       
     1233       
     1234        // On charge les paramÚtres de correction des antennes toutes les demi-secondes
     1235
     1236        if ( compt%500 == 0  && tv.tv_usec/1.0E6 > 0.5 )
     1237        {
     1238            for (int i=1; i<SocketsNumber; i++)
     1239            {
     1240                if (Sockets[i].Connected)
     1241                {
     1242                    // Si l'antenne i est connectée, on charge les paramÚtres
     1243                    Sockets[i].AlignementAntenne->TransmettreParametresClasseAstro(Annee, Mois, Jour, Heu, Min, Sec, Longitude, Latitude, Pression, Temp);         
     1244                   
     1245                    Sockets[i].AlignementAntenne->ChargementParametresAlignement(Sockets[i].IP, "/home/" + (string)getenv("USER") + "/AlignementAntennes.cfg", targetRA * 15 * Pidiv180, targetDEC * Pidiv180);
     1246                }
     1247            }
     1248        }
     1249    }
     1250
    8991251
    9001252
     
    9461298                        // on garde en stock la deuxiÚme partie de la trame
    9471299                        // pour un traitement ultérieur
     1300
    9481301                        buffereponse = reponse.substr(pos + 1);
    9491302
    9501303                        // Partie traitée
     1304
    9511305                        reponse = reponse.substr(0, pos);
    952                        
    953                         IDLog("Reponse recue de %s : %s\n", Sockets[i].IP.c_str(), reponse.c_str());
     1306
     1307                        // on l'affiche dans le log
     1308
     1309                        IDLog("Reponse recue de %s : %s\n", Sockets[i].IP.c_str(), reponse.c_str());
    9541310
    9551311                        // On vérifie ici les acknowledges
     1312
    9561313                        if ((reponse.find("ACK") != string::npos) && (reponse.find("NACK") == string::npos))
    9571314                        {
    9581315                            if (reponse.find("POSITION")  != string::npos)
    9591316                            {
    960                                 Sockets[i].ack_pos=true;
     1317                                Sockets[i].ack_pos   = true;
    9611318                            }
    9621319                            else if (reponse.find("GOTO") != string::npos)
    9631320                            {
    964                                 Sockets[i].ack_goto=true;
     1321                                Sockets[i].ack_goto  = true;
    9651322                            }
    9661323                            else if (reponse.find("PARK") != string::npos)
    9671324                            {
    968                                 Sockets[i].ack_park=true;
     1325                                Sockets[i].ack_park  = true;
    9691326                            }
    9701327                            else if (reponse.find("ABORT")!= string::npos)
    9711328                            {
    972                                 Sockets[i].ack_abort=true;
     1329                                Sockets[i].ack_abort = true;
    9731330                            }
    9741331                        }
    9751332                        else
    9761333                        {
    977                             //réponse à la requête POSITION
     1334                            // Réponse à la requête POSITION
    9781335
    9791336                            if (reponse.find("POSITION") != string::npos)
    9801337                            {
     1338                                // Il y a une erreur signalée par le microcontroleur
     1339
    9811340                                if (reponse.find("NACK") != string::npos)
    9821341                                {
    983                                     //problÚme concernant la commande P
     1342                                    // ProblÚme concernant la commande P
     1343                                    // On affiche dans la boîte indi un voyant de couleur rouge
     1344                                    // et on affiche un message d'erreur
     1345
    9841346                                    OnCoordSetSP.s = IPS_ALERT;
     1347
    9851348                                    IDSetSwitch(&OnCoordSetSP, "ALERTE antenne %s : position de l antenne inconnue !\n",
    9861349                                                Sockets[i].IP.c_str());
     1350
     1351                                    // La position de l'antenne st donc inconnue
     1352
    9871353                                    Sockets[i].PosValides = false;
    988                                     // Si la position de l'antenne est inconnue, on déconnecte l'antenne
     1354
     1355                                    // On déconnecte l'antenne
     1356
    9891357                                    Sockets[i].Connected  = false;
    9901358                                }
    9911359                                else if (Sockets[i].ack_pos)
    992                                 {                             
    993                                     if ( Sockets[i].PosValides = (ExtractPosition(reponse, &Sockets[i].Pos) == true) )
    994                                     {
    995                                       OnCoordSetSP.s = IPS_OK;
    996                                       IDSetSwitch(&OnCoordSetSP, "Antenne %s : POSITION OK  (x=%i, y=%i)\n",
    997                                                 Sockets[i].IP.c_str(), Sockets[i].Pos.x, Sockets[i].Pos.y);
    998                                     }
    999                                     else
    1000                                     {
    1001                                       OnCoordSetSP.s = IPS_ALERT;
    1002                                       IDSetSwitch(&OnCoordSetSP, "Antenne %s : La position n est pas valide !\n",
    1003                                                 Sockets[i].IP.c_str());
    1004                                     }
    1005                                      
     1360                                {
     1361                                    // La position devrait être valide si on arrive ici...
     1362
     1363                                    if ( Sockets[i].PosValides = (ExtractPosition(reponse, &Sockets[i].Pos) == true) )
     1364                                    {
     1365                                        // La fonction extractPositon confirme que les positions transmises
     1366                                        // par le microcontrÃŽleur sont valides
     1367
     1368                                        OnCoordSetSP.s = IPS_OK;
     1369
     1370                                        // message dans les logs
     1371
     1372                                        IDSetSwitch(&OnCoordSetSP, "Antenne %s : POSITION OK  (x=%i, y=%i)\n",
     1373                                                    Sockets[i].IP.c_str(), Sockets[i].Pos.x, Sockets[i].Pos.y);
     1374                                    }
     1375                                    else
     1376                                    {
     1377                                        // Erreur repérée par la fonction ExtractPosition
     1378
     1379                                        OnCoordSetSP.s = IPS_ALERT;
     1380
     1381                                        // On en informe l'utilisateur
     1382
     1383                                        IDSetSwitch(&OnCoordSetSP, "Antenne %s : La position n est pas valide !\n",
     1384                                                    Sockets[i].IP.c_str());
     1385                                    }
    10061386                                }
    10071387                            }
     
    10131393                                if (reponse.find("NACK") != string::npos)
    10141394                                {
     1395                                    // Une erreur  est retournée par le microcontroleur concernant la commande Park
     1396                                    // On affiche le voyant Park en rouge dans la boîte indi...
     1397
    10151398                                    ParkSP.s = IPS_ALERT;
     1399
     1400                                    // ... et on affiche un message d'erreur
     1401
    10161402                                    IDSetSwitch(&ParkSP, "ALERTE antenne %s : erreur PARK !\n", Sockets[i].IP.c_str());
    10171403                                }
    10181404                                else if (Sockets[i].ack_park && reponse.find("OK")!=string::npos)
    10191405                                {
     1406                                    // PARK ok !
     1407
    10201408                                    ParkSP.s = IPS_OK;
     1409
    10211410                                    IDSetSwitch(&ParkSP, "Antenne %s : PARK OK\n",  Sockets[i].IP.c_str());
    10221411                                }
     
    10291418                                if (reponse.find("NACK") != string::npos)
    10301419                                {
     1420                                    // Une erreur  est retournée par le microcontroleur concernant la commande Abort
     1421                                    // On affiche le voyant Park en rouge dans la boîte indi...
     1422
    10311423                                    AbortSlewSP.s = IPS_ALERT;
     1424
     1425                                    // ... et on affiche un message d'erreur
     1426
    10321427                                    IDSetSwitch(&AbortSlewSP, "ALERTE antenne %s : erreur ABORT !\n",  Sockets[i].IP.c_str());
    10331428                                }
    10341429                                else if (Sockets[i].ack_abort && reponse.find("OK")!=string::npos)
    10351430                                {
     1431                                    // OK !
     1432
    10361433                                    AbortSlewSP.s = IPS_OK;
     1434
    10371435                                    IDSetSwitch(&AbortSlewSP, "Antenne %s : ABORT OK\n",  Sockets[i].IP.c_str());
    10381436                                }
    1039 
    10401437                            }
    10411438
     
    10461443                                if (reponse.find("NACK") != string::npos)
    10471444                                {
     1445                                    // Une erreur  est retournée par le microcontroleur concernant la commande Goto
     1446                                    // On affiche le voyant Park en rouge dans la boîte indi...
     1447
    10481448                                    OnCoordSetSP.s = IPS_ALERT;
     1449
     1450                                    // Message d'erreur
     1451
    10491452                                    IDSetSwitch(&OnCoordSetSP, "ALERTE antenne %s : Erreur GOTO !\n",  Sockets[i].IP.c_str());
     1453
     1454                                    // On déconnecte l'antenne. Elle ne semble pas en mesure d'executer les ordres goto
     1455
    10501456                                    DeconnecterSocket(i);
    10511457                                }
     
    10611467                                        Sockets[i].GotoOk = true;
    10621468
     1469                                        // Voyant en vert dans la boîte Indi
     1470
     1471                                        OnCoordSetSP.s = IPS_OK;
     1472
    10631473                                        // Message pour l'utilisateur
    1064                                        
    1065                                         OnCoordSetSP.s = IPS_OK;
     1474
    10661475                                        IDSetSwitch(&OnCoordSetSP, "Antenne %s : GOTO OK.\n",  Sockets[i].IP.c_str());
    10671476
    10681477                                        // Fin du Goto pour toutes les antennes ?
    1069 
    1070                                         int num=0;
     1478                                        // On compte les antennes connectées qui ont réalisé le dernier ordre goto
     1479
     1480                                        int num = 0;
    10711481
    10721482                                        for (int j=1; j<SocketsNumber; j++)
    1073                                         {
    1074                                           if (Sockets[j].Connected)
     1483                                        {
     1484                                            if (Sockets[j].Connected)
    10751485                                            {
    10761486                                                if (Sockets[j].GotoOk) num++;
    10771487                                            }
    1078                                         }
     1488                                        }
     1489
     1490                                        // Si le nombre d'antennes connectées est >0
     1491                                        // et que toutes les antennes connectées ont
     1492                                        // réalisé le goto alors...
    10791493
    10801494                                        if ((num == AntennesConnectees()) && (num>0))
    10811495                                        {
    1082                                             // C'est bon ! Tout marche bien...
     1496                                            // C'est bon ! Tout marche bien...
    10831497                                            // On actualise l'AR et la dec dans la boîte de dialogue
    10841498
     
    10861500                                            lastDEC = targetDEC;
    10871501
    1088                                             // On a fini le mouvement. On attend le prochain goto...
    1089 
    1090                                             ActualisationPosition=false;
     1502                                            // On a fini le mouvement. Il n'y a donc plus d'étape à faire
     1503                                            // dans le processus de réalisation d'un goto
     1504                                            // RealisationGoto vaut donc false
     1505
     1506                                            RealisationGoto = false;
    10911507
    10921508                                            // Réinitialisation des paramÚtres des antennes en vue d'un prochain goto
     
    10951511
    10961512                                            // On dessine les voyants de la boîte de dialogue en vert
     1513
    10971514                                            OnCoordSetSP.s = IPS_OK;
    10981515                                            EquatorialCoordsWNP.s = IPS_OK;
     
    11001517
    11011518                                            // Confirmation dans la boîte de dialogue que toutes
    1102                                             // les antennes sont OK         
    1103                                             OnCoordSetSP.s = IPS_OK;
     1519                                            // les antennes sont OK
     1520
    11041521                                            IDSetSwitch(&OnCoordSetSP, "GOTO OK !");
    1105                                            
    1106                                             UpdateGoto=true;
    1107                                         }                                       
     1522
     1523                                            UpdatedGoto = true;
     1524                                        }
    11081525                                    }
    11091526                                }
     
    11131530                        // On passe à la trame suivante si memreponse n'est pas vide
    11141531
    1115                         reponse=buffereponse;
    1116                         pos=reponse.find("\n");
     1532                        reponse = buffereponse;
     1533                        pos     = reponse.find("\n");
    11171534                    }
    11181535                }
    11191536                catch (SocketException& e) //Aïe
    11201537                {
     1538                    // Une exception concerne le socket i
     1539
     1540                    // On déconnecte l'antenne pour plus de sécurité
     1541
    11211542                    DeconnecterSocket(i);
    11221543
     
    11411562            // pour réaliser un goto
    11421563
    1143             ActualisationPosition = false;
     1564            RealisationGoto = false;
    11441565
    11451566            // On envoie l'ordre ABORT à toutes les antennes
     
    11531574            }
    11541575
     1576            // Message à destination de l'utilisateur et des logs
     1577
    11551578            IDSetSwitch(&OnCoordSetSP, "ABORT OK !");
    11561579
     
    11611584            //Pour permettre de refaire un abort
    11621585
    1163             Abort=false;
     1586            Abort = false;
    11641587        }
    11651588
     
    11761599            // pour réaliser un goto
    11771600
    1178             ActualisationPosition = false;
     1601            RealisationGoto = false;
    11791602
    11801603            // On envoie l'ordre PARK à toutes les antennes
     
    11961619            //Pour permettre de refaire un park
    11971620
    1198             Park=false;
     1621            Park = false;
    11991622        }
    12001623
     
    12031626        // Gestion du suivi
    12041627
    1205         if ((Suivi) && (UpdateGoto))
     1628        if ((Suivi) && (UpdatedGoto))
    12061629        {
    12071630            // Délais entre deux actualisations
    12081631
    1209             double delai=ActualisationTM1 / 3600.0 / 24.0;   // Actualisation toutes les 15 minutes en mode transit
    1210 
    1211             if (TrackingMode==2) delai=ActualisationTM2 / 3600.0 / 24.0;   //et 5 secs en mode tracking
     1632            double delai = ActualisationTMTransit / 3600.0 / 24.0;   // Actualisation toutes les 15 minutes en mode transit (par défaut)
     1633
     1634            if (TrackingMode == 2) delai = ActualisationTMTracking / 3600.0 / 24.0;   //et 5 secs en mode tracking (par défaut)
    12121635
    12131636
     
    12161639            if (GetJJ() - JJAnc > delai)
    12171640            {
    1218                 UpdateGoto = false;
     1641                // Cette variable vaudra true lorsque le goto aura été réalisé
     1642
     1643                UpdatedGoto = false;
    12191644
    12201645                // Conversion des coordonnées en pas moteur
     
    12261651                InitAntennes();
    12271652
    1228                 ActualisationPosition = true;
     1653                // On lance le processus d'actualisation du goto
     1654
     1655                RealisationGoto = true;
    12291656
    12301657                // On sauvegarde la date
     
    12431670                    if (Suivi) IDLog("Arrêt du suivi !");
    12441671
    1245                     ActualisationPosition=false;
     1672                    RealisationGoto=false;
    12461673
    12471674                    Suivi=false;
     
    12541681
    12551682
    1256         // Exécution de la procédure complÚte de lecture de la position de l'antenne
    1257         // puis envoi d'une commande Goto
    1258 
    1259         if (ActualisationPosition)
     1683        // Exécution de la procédure complÚte d'un goto :
     1684        // 1Úre étape : envoi de la commande POSITION à toutes les antennes
     1685        // 2Úme étape : Vérification de l'acknowledge de la commande POSITION pour chaque antenne
     1686        // 3Úme étape : Les positions retournées par les antennes sont-elles valides ?
     1687        // 4Úme étape : Si oui, envoie de la commande goto à toutes les antennes
     1688        // 5Úme étape : est-ce que toutes les antennes ont envoyé l'acknowledge de la commande goto ?
     1689        // 6Úme étape : les antennes ont toutes répondu GOTO OK !
     1690
     1691        if (RealisationGoto)
    12601692        {
    12611693            for (int i=1; i<SocketsNumber; i++)
    12621694            {
     1695                // On ne parle qu'aux antennes connectées
     1696
    12631697                if (Sockets[i].Connected)
    12641698                {
     1699                    // En fonction de l'étage de la réalisation d'un goto par l'antenne i
     1700
    12651701                    switch (Sockets[i].etape)
    12661702                    {
    12671703
    1268                         //Envoi de la commande POS
     1704                        // Envoi de la commande POS
    12691705
    12701706                    case 0 :
    12711707                    {
     1708                        // On doit intialiser l'acknowledge à false
     1709
    12721710                        Sockets[i].ack_pos    = false;
     1711
     1712                        // et considérer que la position de l'antenne n'est pas valide
     1713
    12731714                        Sockets[i].PosValides = false;
    12741715
     1716                        // avant d'envoyer l'ordre POSITION
     1717
    12751718                        if (!POSITION(i)) Sockets[i].sendalertes++;
     1719
     1720                        // On passe à l'étage suivante
    12761721
    12771722                        Sockets[i].etape++;
     
    12861731                        if (Sockets[i].ack_pos)
    12871732                        {
    1288                             // tout marche bien
     1733                            // tout marche bien. On a bien reçu l'acknowledge de l'antenne i
     1734
     1735                            // Il n'y a donc aucune attente supplémentaire pour recevoir la réponse
    12891736                            Sockets[i].AttenteExecution = 0;
     1737
     1738                            // Pas d'anomalie à consigner
    12901739                            Sockets[i].AnomaliesExecution = 0;
     1740
     1741                            // On passe à l'étape suivante
    12911742                            Sockets[i].etape++;
    1292                             i--; //permet de revenir sur ce même socket malgré la boucle
    1293                             // -> plus rapide
     1743
     1744                            //permet de rester sur le même socket malgré la boucle -> plus rapide
     1745                            i--;
    12941746                        }
    12951747                        else
    12961748                        {
    1297                             // on réitÚre l'ordre précédent si rien ne se passe
     1749                            // On réitÚre l'ordre précédent si rien ne se passe
    12981750
    12991751                            // On garde une trace de l'anomalie
     1752
    13001753                            Sockets[i].AttenteExecution++;
    13011754
    13021755                            if (Sockets[i].AttenteExecution > MAXATTENTE)
    13031756                            {
    1304                                 // on recommence depuis le début
     1757                                // on recommence depuis le début.
     1758                                // Peut-être que l'antenne n'a pas reçu l'ordre ?
    13051759                                Sockets[i].etape = 0;
    13061760                                Sockets[i].AttenteExecution = 0;
     1761
     1762                                // Pas de réponse. On consigne une erreur grave
    13071763                                Sockets[i].AnomaliesExecution++;
    13081764                            }
    13091765
    1310                             // Toujours rien -> plus sérieux : il faut déconnecter l'antenne
     1766                            // Les erreurs graves s'accumulent. Pas de réponse aprÚs plusieurs minutes
     1767                            // Il faut déconnecter l'antenne
    13111768                            if (Sockets[i].AnomaliesExecution > MAXANOMALIES)
    13121769                            {
    1313                                 OnCoordSetSP.s = IPS_ALERT;
     1770                                //Voyant en rouge dans la boîte Indi
     1771
     1772                                OnCoordSetSP.s = IPS_ALERT;
     1773
     1774                                //Message à l'attentnio de l'utilisateur
    13141775                                IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : pas d acknowledge recu apres l ordre POSITION. \
    1315     Deconnexion de l antenne.", Sockets[i].IP.c_str());
     1776Deconnexion de l antenne.", Sockets[i].IP.c_str());
     1777
     1778                                // On déconnecte l'antenne
    13161779                                DeconnecterSocket(i);
    13171780                            }
     
    13271790                        if (Sockets[i].PosValides)
    13281791                        {
     1792                            // Tout vas bien
     1793                            // On ne consigne aucune anomalie
    13291794                            Sockets[i].AttenteExecution = 0;
    13301795                            Sockets[i].AnomaliesExecution = 0;
    1331                             Sockets[i].etape++; // on passe à l'étape suivante
     1796
     1797                            //On passe à l'étape suivante
     1798                            Sockets[i].etape++;
    13321799                        }
    13331800                        else
    13341801                        {
    13351802                            // on réitÚre l'ordre précédent si rien ne se passe
     1803
    13361804                            Sockets[i].AttenteExecution++;
    13371805
    13381806                            if (Sockets[i].AttenteExecution > MAXATTENTE)
    13391807                            {
    1340                                 // on attend encore la réponse posvalides                               
     1808                                // on attend encore la réponse posvalides
     1809
    13411810                                Sockets[i].etape = 2;
    13421811                                Sockets[i].AttenteExecution = 0;
     1812
     1813                                // On consigne une erreur grave. L'antenne tarde à répondre
    13431814                                Sockets[i].AnomaliesExecution++;
    13441815                            }
    13451816
     1817                            // Aucune réponse de l'antenne depuis plusieurs minutes
     1818                            // On la déconnecte
    13461819                            if (Sockets[i].AnomaliesExecution > MAXANOMALIES)
    13471820                            {
    1348                                 OnCoordSetSP.s = IPS_ALERT;
     1821                                // Voyant en rouge
     1822
     1823                                OnCoordSetSP.s = IPS_ALERT;
     1824
     1825                                //Message d'erreur
    13491826                                IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : la position retournee n est pas valide. \
    1350     Deconnexion de l antenne.", Sockets[i].IP.c_str());
     1827Deconnexion de l antenne.", Sockets[i].IP.c_str());
     1828
     1829                                //Déconnexion de l'antenne
    13511830                                DeconnecterSocket(i);
    13521831                            }
     
    13541833                    }
    13551834                    break;
     1835
     1836
     1837
     1838                    // On peut remarquer qu'il n'y a pas de case 3 ici...
     1839                    // L'envoie de la commande goto se fait portant pendant l'étape 3 en dehors du switch
     1840                    // Voir le code plus loin...
    13561841
    13571842
     
    13731858                            if (Sockets[i].AttenteExecution > MAXATTENTE)
    13741859                            {
    1375                                 // On prolonge l'attente                                
     1860                                // On prolonge l'attente pour recevoir l'acknowledge du goto
    13761861                                Sockets[i].etape = 4;
    13771862                                Sockets[i].AttenteExecution = 0;
     
    13811866                            if (Sockets[i].AnomaliesExecution > MAXANOMALIES)
    13821867                            {
    1383                                 OnCoordSetSP.s = IPS_ALERT;
    1384                                 IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : pas d acknowledge recu apres l ordre GOTO. \
    1385     Deconnexion de l antenne.", Sockets[i].IP.c_str());
     1868                                OnCoordSetSP.s = IPS_ALERT;
     1869
     1870                                IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : pas d acknowledge recu apres l ordre GOTO. Deconnexion de l antenne.", Sockets[i].IP.c_str());
     1871
    13861872                                DeconnecterSocket(i);
    13871873                            }
     
    13971883                        if (Sockets[i].GotoOk)
    13981884                        {
     1885                            // On a bien reçu Goto Ok pour l'antenne i !
     1886
    13991887                            Sockets[i].AttenteExecution = 0;
    14001888                            Sockets[i].AnomaliesExecution = 0;
     1889
     1890                            //On passe à l'étape suivante
    14011891                            Sockets[i].etape++;
    14021892                        }
     
    14081898                            if (Sockets[i].AttenteExecution > MAXATTENTE)
    14091899                            {
    1410                                 // On prolonge l'attente
    1411                                
     1900                                // On prolonge l'attente afin de recevoit un GOTO OK
     1901
    14121902                                Sockets[i].etape = 5;
    14131903                                Sockets[i].AttenteExecution = 0;
     
    14151905                            }
    14161906
    1417                             // On déconnecte l'antenne s'il n'y a pas de coonfirmation du goto au bout de 2 minutes   
     1907                            // On déconnecte l'antenne s'il n'y a pas de coonfirmation du goto au bout de 2 minutes
    14181908                            if (Sockets[i].AnomaliesExecution > MAXANOMALIESGOTO)
    14191909                            {
    1420                                 OnCoordSetSP.s = IPS_ALERT;
    1421                                 IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : l antenne n a pas renvoye GOTO/OK. \
    1422     Deconnexion de l antenne.", Sockets[i].IP.c_str());
     1910                                // Alerte sur une antenne
     1911                                OnCoordSetSP.s = IPS_ALERT;
     1912
     1913                                // Message d'erreur
     1914                                IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : l antenne n a pas renvoye GOTO/OK. Deconnexion de l antenne.", Sockets[i].IP.c_str());
     1915
     1916                                //Déconnexion de l'antenne
    14231917                                DeconnecterSocket(i);
    14241918                            }
     
    14331927
    14341928        ///////////////////////////////////////
    1435         //On attend que toutes les antennes soient prêtes pour lancer l'ordre Goto -> meilleure synchronisation
    1436 
    1437         int num=0;
     1929        // Traitement de l'étape 3 de la réalisation d'un goto
     1930        // On place cette partie du traitement en dehors du switch et de la boucle
     1931        // pour pouvoir envoyer les ordres gotos à toutes les antennes lorsque l'on a la confirmation
     1932        // qu'elles sont toutes prêtes à executer cet ordre (être à l'étape 3 pour un socket)
     1933        // -> meilleure synchronisation
     1934
     1935        // On compte les antennes rendues à l'étape 3 et qui attendent
     1936
     1937        int num = 0;
    14381938
    14391939        for (int i=1; i<SocketsNumber; i++)
    14401940        {
     1941            // Uniquement les antennes connectées
     1942
    14411943            if (Sockets[i].Connected)
    14421944            {
    1443                 if (Sockets[i].etape == 3) num++; //fin de la procédure ActualisationPosition.
    1444                 // num antennes sont prêtes à recevoir l'ordre GOTO
     1945                if (Sockets[i].etape == 3) num++; // num antennes sont prêtes à recevoir l'ordre GOTO
    14451946            }
    14461947        }
     1948
     1949        // Toutes les antennes connectées sont prêtes à recevoir l'ordre goto
    14471950
    14481951        if ((num == AntennesConnectees()) && (num>0))
     
    14521955                if (Sockets[i].Connected)
    14531956                {
     1957                    // On envoie l'ordre
     1958
    14541959                    Sockets[i].ack_goto = false;
    14551960                    Sockets[i].AttenteExecution = 0;
    14561961                    Sockets[i].AnomaliesExecution = 0;
    14571962
    1458                     if (!GOTO(i, TargetPosition.x - Sockets[i].Pos.x - Sockets[i].Delta.x, TargetPosition.y - Sockets[i].Pos.y - Sockets[i].Delta.y)) Sockets[i].sendalertes++;
     1963                    if (!GOTO(i, Sockets[i].TargetPosition.x - Sockets[i].Pos.x, Sockets[i].TargetPosition.y - Sockets[i].Pos.y )) Sockets[i].sendalertes++;
    14591964
    14601965                    Sockets[i].etape++;
     
    14641969
    14651970        ///////////////////////////////////////
    1466         // Détection d'anomalies sur la socket. Déconnexion du micro-cont ?
     1971        // Opération garbage
     1972        // Détection d'anomalies sur le socket i.
     1973        // Ce n'est pas normal ici. Il faut déconnecte l'antenne
    14671974
    14681975        for (int i=1; i<SocketsNumber; i++)
     
    14721979                if (Sockets[i].sendalertes > 0)
    14731980                {
    1474                     OnCoordSetSP.s = IPS_ALERT;
     1981                    // Alarme dans la boîte Indi
     1982
     1983                    OnCoordSetSP.s = IPS_ALERT;
     1984
     1985                    // Erreur dans les logs
     1986
    14751987                    IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : deconnexion de l antenne.", Sockets[i].IP.c_str());
     1988
     1989                    // Déconnexion antenne
    14761990
    14771991                    DeconnecterSocket(i);
     
    14801994        }
    14811995    }
    1482    
     1996
    14831997    //incrémentation du compteur
     1998
    14841999    compt++;
    14852000}
     
    15112026        InitAntennes();
    15122027
     2028        // On garde la trace du début du Goto pour enchainer les actualisations
     2029
    15132030        JJAnc = GetJJ();
    1514        
    1515         ADDEC2Motor(targetRA, targetDEC);
     2031
     2032        // Conversion des coordonnées horaires en pas moteur
     2033
     2034        ADDEC2Motor(targetRA, targetDEC);
     2035
     2036        // Mode transit activé
    15162037
    15172038        TrackingMode = 1;
    15182039
     2040        // On suit un objet
     2041
    15192042        Suivi = true;
    15202043
    1521         UpdateGoto = false;
    1522 
    1523         ActualisationPosition = true;
     2044        // Aucun goto n'a été encore réalisé
     2045
     2046        UpdatedGoto = false;
     2047
     2048        // Mais on se lance dans la réalisation d'un goto
     2049
     2050        RealisationGoto = true;
    15242051
    15252052        break;
     
    15392066        InitAntennes();
    15402067
    1541         JJAnc=GetJJ();
    1542        
    1543         ADDEC2Motor(targetRA, targetDEC);
     2068        JJAnc = GetJJ();
     2069
     2070        ADDEC2Motor(targetRA, targetDEC);
    15442071
    15452072        TrackingMode = 2;
     
    15472074        Suivi = true;
    15482075
    1549         UpdateGoto = false;
    1550 
    1551         ActualisationPosition = true;       
     2076        UpdatedGoto = false;
     2077
     2078        RealisationGoto = true;
    15522079
    15532080        break;
     
    15812108
    15822109        // On lance le thread !
    1583 
    1584         Exit=false;
     2110        // Exit ne faudra true que lorsque sera venu le moment de sortir !
     2111
     2112        Exit = false;
     2113
     2114        // Création du thread
    15852115
    15862116        if (pthread_create (&th1, NULL, (void*(*)(void*))LancementThread, this) < 0)
     
    15922122
    15932123    case ISS_OFF:
    1594 
    1595         // On sort du thread
    1596 
    1597         Exit = true;
    1598         sleep(1);
    1599         pthread_join (th1, NULL);
    1600         InitThreadOK = false;
    16012124
    16022125        // Etat des voyants
     
    16212144        SocketsNumber = 1;
    16222145
     2146        // On sort du thread
     2147
     2148        // On dit au thread de sortir de la boucle
     2149
     2150        Exit = true;
     2151
     2152        // Désactiver la boucle de traitement des messages des ISPOLL
     2153
     2154        InitThreadOK = false;
     2155
     2156        // On laisse 1 s au thread pour sortir de la boucle
     2157
     2158        sleep(1);
     2159
     2160        // On détruit le thread
     2161
     2162        pthread_join (th1, NULL);
     2163
     2164        // on sort du programme
     2165
     2166        exit(EXIT_SUCCESS);
     2167
    16232168        break;
    16242169    }
     
    16302175/**************************************************************************************
    16312176**  Envoie une commande sur le socket numsocket
     2177**
    16322178***************************************************************************************/
    16332179
     
    16392185    {
    16402186        sprintf(chaine, "%s%s\n", Commande, Params);
    1641        
    1642         Sockets[numsocket].new_sock << chaine;
    1643        
    1644         IDLog("Commande envoyee a %s: %s", Sockets[numsocket].IP.c_str(), chaine);
     2187
     2188        Sockets[numsocket].new_sock << chaine;
     2189
     2190        IDLog("Commande envoyee a %s: %s", Sockets[numsocket].IP.c_str(), chaine);
    16452191    }
    16462192    catch (SocketException& e)
    16472193    {
     2194        // Consignation d'une anomalie sur le socket
     2195
    16482196        DeconnecterSocket(numsocket);
    16492197
     
    16612209/**************************************************************************************
    16622210** Commande POSITION
     2211**
    16632212***************************************************************************************/
    16642213
     
    16702219/**************************************************************************************
    16712220** Commande PARK
     2221**
    16722222***************************************************************************************/
    16732223
     
    16792229/**************************************************************************************
    16802230** Commande ABORT
     2231**
    16812232***************************************************************************************/
    16822233
     
    16892240/**************************************************************************************
    16902241** Commande GOTO
     2242**
    16912243***************************************************************************************/
    16922244
     
    17002252    sensAz  = 1;
    17012253
     2254    // gestion des signes des deltas
     2255
    17022256    if ( deltaAz < 0 )
    17032257    {
     
    17132267
    17142268    // Vérification du nombre de pas à faire au niveau de l'axe azimut
    1715     // Rappel : un tour complet autour de l'axe az fait 4000 pas codeur (#define NBREPASCODEURSAZ dans BAO.h)
    1716 
    1717     // problÚme 1 : si deltaAz > à un demi-tours - soit 2000 pas alors
     2269    // Rappel : un tour complet autour de l'axe az fait 4000 pas codeur (voir #define NBREPASCODEURSAZ dans BAO.h)
     2270
     2271    // problÚme 1 : si deltaAz > à un demi-tours - soit 2000 pas codeur alors
    17182272    // on fait le trajet dans le sens inverse pour aller plus vite
    17192273
     
    17302284    {
    17312285        deltaAz = NBREPASCODEURSAZ - deltaAz;
     2286
    17322287        sensAz = 1 - sensAz;
    17332288    }
     
    17352290    //on envoie les coordonnées au driver
    17362291
    1737     if (sensAz == 1 )  sensAz='f'; else sensAz='b';
    1738    
    1739     if (sensAlt == 1 ) sensAlt='f'; else sensAlt='b';
     2292    (sensAz == 1 ) ? sensAz='f' : sensAz='b';
     2293
     2294    (sensAlt == 1 ) ? sensAlt='f': sensAlt='b';
    17402295
    17412296    sprintf(Params, "%c%04i%c%04i", sensAz, deltaAz, sensAlt, deltaAlt);
     
    18382393
    18392394
    1840 /**************************************************************************************
    1841 **
    1842 ***************************************************************************************/
    1843 void BAO::get_initial_data()
    1844 {
    1845     //  IDSetNumber (&EquatorialCoordsRNP, NULL);
    1846 }
    1847 
    1848 /**************************************************************************************
    1849 **
    1850 ***************************************************************************************/
    1851 void BAO::slew_error(int slewCode)
    1852 {
    1853     OnCoordSetSP.s = IPS_IDLE;
    1854 
    1855     if (slewCode == 1)
    1856         IDSetSwitch (&OnCoordSetSP, "Object below horizon.");
    1857     else if (slewCode == 2)
    1858         IDSetSwitch (&OnCoordSetSP, "Object below the minimum elevation limit.");
    1859     else
    1860         IDSetSwitch (&OnCoordSetSP, "Slew failed.");
    1861 }
    18622395
    18632396/**************************************************************************************
     
    19292462
    19302463
     2464
  • BAORadio/libindi/libindi/drivers/telescope/BAO.h

    r619 r642  
    2323#include <fstream>
    2424
     25#include <termios.h>
     26#include <unistd.h>
     27
    2528#include <config.h>
    26 
    2729#include "indicom.h"
    28 
    29 #include "Socket.h"
    3030#include "indidevapi.h"
    3131#include "indicom.h"
    32 #include "ServerSocket.h"
    33 #include "SocketException.h"
    34 #include "astro.h"
    35 #include "filetools.h"
    36 
    37 #define MAXCARACTERES 1024
    38 
    39 #define MAXATTENTE 80                // Si une commande ne recoit pas d'acknowledge. Alors refaire 80 tentatives en renvoyant la commande
    40 #define MAXANOMALIES 2               // Si pas de réponse au bout de 80 tentatives -> erreur critique -> socket perdu ?
    41 #define MAXANOMALIESGOTO 1500
    42 
    43 #define NBREPASCODEURSAZ  4000
    44    
     32#include "../communs/const.h"
     33#include "../communs/Socket.h"
     34#include "../communs/ServerSocket.h"
     35#include "../communs/SocketException.h"
     36#include "../communs/astro.h"
     37#include "../communs/alignement.h"
     38
    4539
    4640using namespace std;
     41
    4742
    4843struct Position
     
    5247};
    5348
     49
    5450struct DefSocket
    5551{
    56     ServerSocket new_sock;           // socket permettant de gérer la connexion avec une antennes
    57 
    58     string IP;                       // IP de l'antenne
    59 
    60     bool Connected;                  // le micro-contrÃŽleur est-il connecté ?
    61     bool PosValides;                 // le micro-contrÃŽleur a-t-il donné une position des moteurs valide ?
    62     char status;                     // status='B' pour busy  'R' pour READY
    63     int sendalertes;                 // une requête 'send' a généré une erreur sur le réseau
    64     int AttenteExecution;            // L'antenne parvient-elle à executer un cycle de commandes ?
    65     int AnomaliesExecution;          // Erreur critique. L'antenne ne répond plus !
    66 
    67     Position Pos;                    // derniÚre position retournée par le microcontrÃŽleur
    68     Position Delta;                  // Corrections en Az et Ha
    69     int etape;                       // étape dans le cycle de commandes/réponses entre PC et microcontroleurs
    70 
    71     bool ack_status;                 // Etat des acknowledges ?
    72     bool ack_pos;                    // le PC a reçu une confirmation du microcont aprÚs un ordre POSITION
    73     bool ack_park;                   // le PC a reçu une confirmation du microcont aprÚs un ordre PARK
    74     bool ack_abort;                  // le PC a reçu une confirmation du microcont aprÚs un ordre ABORT
    75     bool ack_goto;                   // le PC a reçu une confirmation du microcont aprÚs un ordre GOTO
    76     bool GotoOk;                     // Est-ce que le dernier goto est OK ?
     52    ServerSocket new_sock;                  // socket permettant de gérer la connexion avec une antennes
     53
     54    string IP;                              // IP de l'antenne
     55
     56    char status;                            // status='B' pour bus,  'R' pour READY
     57
     58    int sendalertes;                        // une requête 'send' a généré une erreur sur le réseau
     59    int AttenteExecution;                   // L'antenne parvient-elle à executer un cycle de commandes ?
     60    int AnomaliesExecution;                 // Erreur critique. L'antenne ne répond plus !
     61    int etape;                              // étape dans le cycle de commandes/réponses entre PC et microcontroleurs
     62
     63    bool Connected;                         // le micro-contrÃŽleur est-il connecté ?
     64    bool PosValides;                        // le micro-contrÃŽleur a-t-il donné une position des moteurs valide ?
     65    bool ack_status;                        // Etat des acknowledges ?
     66    bool ack_pos;                           // le PC a-t-il reçu une confirmation du microcontroleurs aprÚs un ordre POSITION ?
     67    bool ack_park;                          // le PC a-t-il reçu une confirmation du microcontroleurs aprÚs un ordre PARK ?
     68    bool ack_abort;                         // le PC a-t-il reçu une confirmation du microcontroleurs aprÚs un ordre ABORT ?
     69    bool ack_goto;                          // le PC a-t-il reçu une confirmation du microcontroleurs aprÚs un ordre GOTO ?
     70    bool GotoOk;                            // Est-ce que le dernier goto est OK ?
     71
     72    Position TargetPosition;                // Position à atteindre
     73    Position Pos;                           // derniÚre position retournée par le microcontrÃŽleur
    7774   
    78    
    79 };
    80 
    81 
    82 ServerSocket server( 8000 );         // Le PC et les antennes communiquent par le biais du port 8000 sur le réseau tcp
     75    Alignement *AlignementAntenne;          // Contient les paramÚtres d'alignement de l'antenne 
     76};
     77
     78
     79// Le PC et les antennes communiquent par le biais du port 8000 sur le réseau Ethernet
     80
     81ServerSocket server( 8000 );         
    8382
    8483class BAO : public Astro
     
    8887    ~BAO();
    8988
     89    /*******************************************************/
     90    /* Gestion de l'interface intégrée dans KStars
     91    ********************************************************/
     92
    9093    void ISGetProperties (const char *dev);
    9194    void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
     
    9497    void ISPoll ();
    9598
     99    /*******************************************************/
     100    /* Gestion des threads
     101    ********************************************************/
     102
    96103    void *pThreadSocket ();
    97104    void *pThreadExit ();
    98105
     106    /*******************************************************/
     107    /* Les commandes
     108    ********************************************************/
     109
    99110    bool COMMANDE(int numsocket, char* Commande, char* Params);
    100111    bool ExtractPosition(string str, Position *result);
    101 
    102     void connection_lost();
    103     void connection_resumed();
    104 
    105112    bool STATUS(int numsocket);
    106113    bool POSITION(int numsocket);
     
    108115    bool PARK(int numsocket);
    109116    bool GOTO(int numsocket, int deltaAz, int deltaAlt);
    110     void ADDEC2Motor(double newRA, double newDEC);
     117
     118
     119    /*******************************************************/
     120    /* Connection Routines
     121    ********************************************************/
     122    void init_properties();
     123    void connect_telescope();
     124    bool is_connected(void);
    111125    int  AntennesConnectees();
    112126    void DeconnecterSocket(int num);
    113127    void InitAntennes();
    114     bool ChargementParametresAlignement(string fileName);
    115     bool is_readable( const std::string & file );
    116  
    117     /*******************************************************/
    118     /* Connection Routines
    119     ********************************************************/
    120     void init_properties();
    121     void get_initial_data();
    122     void connect_telescope();
    123     bool is_connected(void);
     128
    124129
    125130    /*******************************************************/
     
    127132    ********************************************************/
    128133    bool process_coords();
    129     int get_switch_index(ISwitchVectorProperty *sp);
     134    int  get_switch_index(ISwitchVectorProperty *sp);
     135    void ADDEC2Motor(double newRA, double newDEC);
    130136
    131137    /*******************************************************/
     
    137143    /* Error handling routines
    138144    ********************************************************/
    139     void slew_error(int slewCode);
    140145    void reset_all_properties();
    141146    void handle_error(INumberVectorProperty *nvp, int err, const char *msg);
    142147    void correct_fault();
    143 
     148    void connection_lost();
     149    void connection_resumed();
    144150
    145151
     
    147153
    148154    enum BAO_STATUS { BAO_TRANSIT, BAO_TRACKING, BAO_PARK };
     155
     156    // ParamÚtres par défaut d'un pilote indi
    149157
    150158    /* Switches */
    151159    ISwitch ConnectS[2];
    152160    ISwitch OnCoordSetS[2];
     161    ISwitch AlignmentS[3];
    153162    ISwitch AbortSlewS[1];
    154163    ISwitch ParkS[1];
     
    159168
    160169    /* Numbers */
    161     //INumber EquatorialCoordsRN[2];
    162170    INumber EquatorialCoordsWN[2];
    163171    INumber GeographicCoordsWN[2];
     172    INumber PressionTempWN[2];
    164173    INumber ActualisationN1[1];
    165174    INumber ActualisationN2[1];
    166 
    167     //INumber SlewAccuracyN[2];
    168     //INumber TrackAccuracyN[2];
    169175
    170176    /* Switch Vectors */
    171177    ISwitchVectorProperty ConnectSP;
    172178    ISwitchVectorProperty OnCoordSetSP;
     179    ISwitchVectorProperty AlignmentSP;
    173180    ISwitchVectorProperty AbortSlewSP;
    174181    ISwitchVectorProperty ParkSP;
    175182
    176183    /* Number Vectors */
    177     //INumberVectorProperty EquatorialCoordsRNP;
    178184    INumberVectorProperty EquatorialCoordsWNP;
    179185    INumberVectorProperty GeographicCoordsWNP;
    180     //INumberVectorProperty SlewAccuracyNP;
    181     //INumberVectorProperty TrackAccuracyNP;
     186    INumberVectorProperty PressionTempWNP;
    182187    INumberVectorProperty ActualisationNP1;
    183188    INumberVectorProperty ActualisationNP2;
     
    191196
    192197protected:
     198
    193199    int SocketsNumber;                   // nbre de sockets utilisés pour connecter les antennes
    194     bool InitThreadOK;                   // Le thread est bien actif
    195     DefSocket Sockets[MAXHOSTNAME + 1];  // Etat de chaque socket. Un socket permet la communication avec une antenne
     200    bool InitThreadOK;                   // Le thread est-t-il  actif ?
     201    DefSocket Sockets[MAXHOSTNAME + 1];  // Définit chaque socket. Un socket permet la communication avec une antenne
    196202    pthread_t th1;                       // le pointeur du thread
    197203
    198204    double JD;                           // Jour julien
    199     double lastRA;                       // Sauvegarde de la derniÚre position avant actualisation
    200     double lastDEC;
     205    double lastRA;                       // Sauvegarde de la derniÚre position avant actualisation, ici l'AD...
     206    double lastDEC;                      // ...et la déclinaison
    201207    double JJAnc;                        // Sauvegarde du jour julien lors de la derniÚre actualisation de la position (fct Goto)
    202     double ActualisationTM1;             // Délais entre deux actualisations dans les modes transit et tracking
    203     double ActualisationTM2;
     208    double ActualisationTMTransit;       // Délai entre deux actualisations dans les modes transit
     209    double ActualisationTMTracking;      //  "                 "                     "     tracking
    204210    double Longitude;                    // Longitude et latitude du lieu d'observation
    205211    double Latitude;
    206     bool   ActualisationPosition;        // Permet de faire les étapes nécessaires pour réaliser un mouvement
     212    double Pression;                     // Pression et température sur le lieu d'observation
     213    double Temp;   
     214    bool   RealisationGoto;              // Permet de réaliser les différentes étapes nécessaires à la réalisation d'un goto
     215                                         // tant qu'un goto n'est pas terminé, ActualisationPosition = true
    207216    bool   Abort;                        // Annulation du mouvement en cours
    208217    bool   Park;                         // On place les antennes dans une position de repos
    209     bool   Suivi;                        // Suivi d'un objet en cours...
    210     bool   UpdateGoto;                   // On peut exécuter un Goto
     218    bool   Suivi;                        // Est-ce que les antennes suivent actuellement un objet ?
     219    bool   UpdatedGoto;                  // On peut exécuter un Goto
    211220    bool   Exit;                         // On ferme le driver
    212221
    213     int    currentSet;                   // Variable interne de l'interface indi
    214     int    lastSet;                      // Variable interne de l'interface indi
    215     int    TrackingMode;                 //1 : Transit           2: Tracking
    216 
    217     Position TargetPosition;             //Position à atteindre en coordonnées équatoriales
     222    int    currentSet;                   // mode de suivi actuel - tracking ou transit
     223    int    lastSet;                      // Variable interne de l'interface indi - ne pas toucher
     224    int    TrackingMode;                 // 1 : Transit           2: Tracking
    218225};
    219226
  • BAORadio/libindi/libindi/drivers/telescope/celestrongps.cpp

    r490 r642  
    525525
    526526         if (IUUpdateSwitch(&MovementNSSP, states, names, n) < 0)
    527                 return;
    528 
    529         current_move = getOnSwitch(&SlewModeSP);
     527        IDLog("fixme!!! - IUUpdateSwitch MovementNSSP\n");
     528        //      return;
     529
     530        current_move = getOnSwitch(&MovementNSSP);
    530531
    531532        // Previosuly active switch clicked again, so let's stop.
     
    569570
    570571         if (IUUpdateSwitch(&MovementWESP, states, names, n) < 0)
    571                 return;
    572 
    573         current_move = getOnSwitch(&SlewModeSP);
     572        IDLog("fixme!!! - IUUpdateSwitch MovementWESP\n");
     573                //return;
     574
     575        current_move = getOnSwitch(&MovementWESP);
    574576
    575577        // Previosuly active switch clicked again, so let's stop.
  • BAORadio/libindi/libindi/drivers/telescope/celestronprotocol.c

    r490 r642  
    286286    {
    287287      slewCmd[2] = 0x10;
    288       slewCmd[3] = 0x24;
     288      slewCmd[3] = 0x25;
    289289    }
    290290  else if(direction == SOUTH)
    291291    {
    292292      slewCmd[2] = 0x11;
    293       slewCmd[3] = 0x24;
     293      slewCmd[3] = 0x25;
    294294    }
    295295  else if(direction == WEST)
  • BAORadio/libindi/libindi/drivers/telescope/lx200driver.c

    r490 r642  
    8888int setCommandXYZ(int fd, int x, int y, int z, const char *cmd);
    8989/* Common routine for Set commands */
    90 int setStandardProcedure(int fd, char * writeData);
     90int setStandardProcedure(int fd, const char * writeData);
    9191/* Set Slew Mode */
    9292int setSlewMode(int fd, int slewMode);
     
    220220  /*if ( (read_ret = portRead(temp_string, -1, LX200_TIMEOUT)) < 1)
    221221     return read_ret;*/
    222   tty_read_section(fd, temp_string, '#', LX200_TIMEOUT, &nbytes_read);
    223  
     222
     223  error_type = tty_read_section(fd, temp_string, '#', LX200_TIMEOUT, &nbytes_read);
     224  tcflush(fd, TCIFLUSH);
     225  if (error_type != TTY_OK)
     226    return error_type;
     227
    224228  temp_string[nbytes_read - 1] = '\0';
    225229 
     
    251255   return error_type;
    252256 
    253   tty_read_section(fd, temp_string, '#', LX200_TIMEOUT, &nbytes_read);
     257  error_type = tty_read_section(fd, temp_string, '#', LX200_TIMEOUT, &nbytes_read);
     258  tcflush(fd, TCIFLUSH);
     259  if (error_type != TTY_OK)
     260    return error_type;
    254261 
    255262  temp_string[nbytes_read - 1] = '\0';
     
    685692**********************************************************************/
    686693
    687 int setStandardProcedure(int fd, char * data)
     694int setStandardProcedure(int fd, const char * data)
    688695{
    689696 char bool_return[2];
  • BAORadio/libindi/libindi/drivers/telescope/lx200driver.h

    r490 r642  
    174174int setCommandXYZ(int fd, int x, int y, int z, const char *cmd);
    175175/* Common routine for Set commands */
    176 int setStandardProcedure(int fd, char * writeData);
     176int setStandardProcedure(int fd, const char * writeData);
    177177/* Set Slew Mode */
    178178int setSlewMode(int fd, int slewMode);
  • BAORadio/libindi/libindi/drivers/telescope/lx200generic.cpp

    r504 r642  
    3333#include "lx200ap.h"
    3434#include "lx200classic.h"
     35#include "lx200fs2.h"
    3536
    3637#include <config.h>
     
    331332  changeLX200ClassicDeviceName(newName);
    332333  changeLX200GPSDeviceName(newName);
     334  changeLX200FS2DeviceName(newName);
    333335}
    334336
     
    464466
    465467   MaxReticleFlashRate = 9;
     468 }
     469 else if (strstr(me, "indi_lx200fs2"))
     470 {
     471   fprintf(stderr , "initilizaing from fs2 device...\n");
     472 
     473   // 2. device = sub_class
     474   telescope = new LX200Fs2();
     475         
     476   if (envDev != NULL)
     477   {
     478           // 1. change device name
     479           changeAllDeviceNames(envDev);
     480           telescope->setCurrentDeviceName(envDev);
     481   }
     482   else
     483   {
     484          // 1. change device name
     485          changeAllDeviceNames("LX200 FS2");
     486      telescope->setCurrentDeviceName("LX200 FS2");
     487   }
     488   
    466489 }
    467490 // be nice and give them a generic device
  • BAORadio/libindi/libindi/drivers/telescope/lx200generic.h

    r490 r642  
    4545 int checkPower(ISwitchVectorProperty *sp);
    4646 int checkPower(ITextVectorProperty *tp);
    47  void handleError(ISwitchVectorProperty *svp, int err, const char *msg);
    48  void handleError(INumberVectorProperty *nvp, int err, const char *msg);
    49  void handleError(ITextVectorProperty *tvp, int err, const char *msg);
     47 virtual void handleError(ISwitchVectorProperty *svp, int err, const char *msg);
     48 virtual void handleError(INumberVectorProperty *nvp, int err, const char *msg);
     49 virtual void handleError(ITextVectorProperty *tvp, int err, const char *msg);
    5050 bool isTelescopeOn(void);
    51  void connectTelescope();
     51 virtual void connectTelescope();
    5252 void slewError(int slewCode);
    5353 void getAlignment();
     
    8080  int    currentSet;
    8181  int    lastSet;
    82  
    8382
    8483};
  • BAORadio/libindi/libindi/drivers/telescope/synscanmount.cpp

    r504 r642  
    22  Copyright(c) 2010 Gerry Rozema. All rights reserved.
    33
    4   This program is free software; you can redistribute it and/or modify it
    5   under the terms of the GNU General Public License as published by the Free
    6   Software Foundation; either version 2 of the License, or (at your option)
    7   any later version.
    8 
    9   This program is distributed in the hope that it will be useful, but WITHOUT
    10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    12   more details.
    13 
    14   You should have received a copy of the GNU General Public License along with
    15   this program; if not, write to the Free Software Foundation, Inc., 59
    16   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    17 
    18   The full GNU General Public License is included in this distribution in the
    19   file called LICENSE.
     4 This library is free software; you can redistribute it and/or
     5 modify it under the terms of the GNU Library General Public
     6 License version 2 as published by the Free Software Foundation.
     7
     8 This library is distributed in the hope that it will be useful,
     9 but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     11 Library General Public License for more details.
     12
     13 You should have received a copy of the GNU Library General Public License
     14 along with this library; see the file COPYING.LIB.  If not, write to
     15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     16 Boston, MA 02110-1301, USA.
    2017*******************************************************************************/
     18
    2119#include "synscanmount.h"
    2220#include "libs/indicom.h"
     
    3937void ISPoll(void *p);
    4038
     39#define isDebug() true
    4140
    4241void ISInit()
     
    110109bool SynscanMount::initProperties()
    111110{
    112     if (isDebug())
     111    //if (isDebug())
    113112        IDLog("Synscan::init_properties\n");
    114113
     
    120119void SynscanMount::ISGetProperties (const char *dev)
    121120{
    122     if (isDebug())
     121    //if (isDebug())
    123122        IDLog("Enter SynscanMount::ISGetProperties %s\n",dev);
    124123
     
    139138    int n1,n2;
    140139
    141     //IDLog("Read Status\n");
     140    //IDLog("SynScan Read Status\n");
    142141    //tty_write(PortFD,(unsigned char *)"Ka",2, &bytesWritten);  //  test for an echo
    143142
     
    147146    {
    148147        //  this is not a correct echo
    149         if (isDebug())
     148        //if (isDebug())
    150149            IDLog("ReadStatus Echo Fail\n");
    151150        IDMessage(deviceName(),"Mount Not Responding");
     
    192191    tty_write(PortFD,"e",1, &bytesWritten);
    193192    numread=tty_read(PortFD,str,18,1, &bytesRead);
    194     if (numread!=18)
     193    if (bytesRead!=18)
     194        //if(str[17] != '#')
    195195    {
    196196        IDLog("read status bytes didn't get a full read\n");
     
    230230    TrackState=SCOPE_SLEWING;
    231231    numread=tty_read(PortFD,str,1,60, &bytesRead);
    232     if (numread!=1||str[0]!='#')
     232    if (bytesRead!=1||str[0]!='#')
    233233    {
    234234        if (isDebug())
     
    258258    tty_write(PortFD,"T0",2, &bytesWritten);
    259259    numread=tty_read(PortFD,str,1,60, &bytesRead);
    260     if (numread!=1||str[0]!='#')
     260    if (bytesRead!=1||str[0]!='#')
    261261    {
    262262        if (isDebug())
     
    268268    tty_write(PortFD,"B0000,4000",10, &bytesWritten);
    269269    numread=tty_read(PortFD,str,1,60, &bytesRead);
    270     if (numread!=1||str[0]!='#')
     270    if (bytesRead!=1||str[0]!='#')
    271271    {
    272272        if (isDebug())
  • BAORadio/libindi/libindi/drivers/telescope/synscanmount.h

    r504 r642  
    22  Copyright(c) 2010 Gerry Rozema. All rights reserved.
    33
    4   This program is free software; you can redistribute it and/or modify it
    5   under the terms of the GNU General Public License as published by the Free
    6   Software Foundation; either version 2 of the License, or (at your option)
    7   any later version.
     4 This library is free software; you can redistribute it and/or
     5 modify it under the terms of the GNU Library General Public
     6 License version 2 as published by the Free Software Foundation.
    87
    9   This program is distributed in the hope that it will be useful, but WITHOUT
    10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    12   more details.
     8 This library is distributed in the hope that it will be useful,
     9 but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     11 Library General Public License for more details.
    1312
    14   You should have received a copy of the GNU General Public License along with
    15   this program; if not, write to the Free Software Foundation, Inc., 59
    16   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    17 
    18   The full GNU General Public License is included in this distribution in the
    19   file called LICENSE.
     13 You should have received a copy of the GNU Library General Public License
     14 along with this library; see the file COPYING.LIB.  If not, write to
     15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     16 Boston, MA 02110-1301, USA.
    2017*******************************************************************************/
    2118
     
    3936        const char *getDefaultName();
    4037
     38        //virtual bool Connect() {return true;}
    4139        bool ReadScopeStatus();
    4240        bool Goto(double,double);
  • BAORadio/libindi/libindi/drivers/telescope/telescope_simulator.cpp

    r504 r642  
    1313std::auto_ptr<ScopeSim> telescope_sim(0);
    1414
    15 #define SLEWRATE        1                               /* slew rate, degrees/s */
     15#define GOTO_RATE       2                               /* slew rate, degrees/s */
     16#define SLEW_RATE       0.5                             /* slew rate, degrees/s */
     17#define FINE_SLEW_RATE  0.1                             /* slew rate, degrees/s */
     18#define SID_RATE        0.004178                        /* sidereal rate, degrees/s */
     19
     20#define GOTO_LIMIT      5                               /* Move at GOTO_RATE until distance from target is GOTO_LIMIT degrees */
     21#define SLEW_LIMIT      2                               /* Move at SLEW_LIMIT until distance from target is SLEW_LIMIT degrees */
     22#define FINE_SLEW_LIMIT 0.5                             /* Move at FINE_SLEW_RATE until distance from target is FINE_SLEW_LIMIT degrees */
     23
    1624#define POLLMS          250                             /* poll period, ms */
    17 #define SIDRATE         0.004178                        /* sidereal rate, degrees/s */
     25
     26#define RA_AXIS         0
     27#define DEC_AXIS        1
     28#define GUIDE_NORTH     0
     29#define GUIDE_SOUTH     1
     30#define GUIDE_WEST      0
     31#define GUIDE_EAST      1
     32
    1833
    1934
     
    8095    currentDEC=15;
    8196    Parked=false;
     97
     98    GuideNSNP = new INumberVectorProperty;
     99    GuideWENP = new INumberVectorProperty;
     100    EqPECNV = new INumberVectorProperty;
     101    GuideRateNP = new INumberVectorProperty;
     102
     103    PECErrNSSP = new ISwitchVectorProperty;
     104    PECErrWESP = new ISwitchVectorProperty;
     105
     106    /* initialize random seed: */
     107      srand ( time(NULL) );
    82108}
    83109
     
    90116{
    91117    return (char *)"Telescope Simulator";
     118}
     119
     120bool ScopeSim::initProperties()
     121{
     122    /* Make sure to init parent properties first */
     123    INDI::Telescope::initProperties();
     124
     125    /* Property for guider support. How many seconds to guide either northward or southward? */
     126    IUFillNumber(&GuideNSN[GUIDE_NORTH], "TIMED_GUIDE_N", "North (sec)", "%g", 0, 10, 0.001, 0);
     127    IUFillNumber(&GuideNSN[GUIDE_SOUTH], "TIMED_GUIDE_S", "South (sec)", "%g", 0, 10, 0.001, 0);
     128    IUFillNumberVector(GuideNSNP, GuideNSN, 2, deviceName(), "TELESCOPE_TIMED_GUIDE_NS", "Guide North/South", MOTION_TAB, IP_RW, 0, IPS_IDLE);
     129
     130    /* Property for guider support. How many seconds to guide either westward or eastward? */
     131    IUFillNumber(&GuideWEN[GUIDE_WEST], "TIMED_GUIDE_W", "West (sec)", "%g", 0, 10, 0.001, 0);
     132    IUFillNumber(&GuideWEN[GUIDE_EAST], "TIMED_GUIDE_E", "East (sec)", "%g", 0, 10, 0.001, 0);
     133    IUFillNumberVector(GuideWENP, GuideWEN, 2, deviceName(), "TELESCOPE_TIMED_GUIDE_WE", "Guide West/East", MOTION_TAB, IP_RW, 0, IPS_IDLE);
     134
     135    /* Simulated periodic error in RA, DEC */
     136    IUFillNumber(&EqPECN[RA_AXIS],"RA_PEC","RA (hh:mm:ss)","%010.6m",0,24,0,15.);
     137    IUFillNumber(&EqPECN[DEC_AXIS],"DEC_PEC","DEC (dd:mm:ss)","%010.6m",-90,90,0,15.);
     138    IUFillNumberVector(EqPECNV,EqPECN,2,deviceName(),"EQUATORIAL_PEC","Periodic Error",MOTION_TAB,IP_RO,60,IPS_IDLE);
     139
     140    /* Enable client to manually add periodic error northward or southward for simulation purposes */
     141    IUFillSwitch(&PECErrNSS[MOTION_NORTH], "PEC_N", "North", ISS_OFF);
     142    IUFillSwitch(&PECErrNSS[MOTION_SOUTH], "PEC_S", "South", ISS_OFF);
     143    IUFillSwitchVector(PECErrNSSP, PECErrNSS, 2, deviceName(),"PEC_NS", "PE N/S", MOTION_TAB, IP_RW, ISR_1OFMANY, 60, IPS_IDLE);
     144
     145    /* Enable client to manually add periodic error westward or easthward for simulation purposes */
     146    IUFillSwitch(&PECErrWES[MOTION_WEST], "PEC_W", "West", ISS_OFF);
     147    IUFillSwitch(&PECErrWES[MOTION_EAST], "PEC_E", "East", ISS_OFF);
     148    IUFillSwitchVector(PECErrWESP, PECErrWES, 2, deviceName(),"PEC_WE", "PE W/E", MOTION_TAB, IP_RW, ISR_1OFMANY, 60, IPS_IDLE);
     149
     150    /* How fast do we guide compared to sideral rate */
     151    IUFillNumber(&GuideRateN[RA_AXIS], "GUIDE_RATE_WE", "W/E Rate", "%g", 0, 1, 0.1, 0.3);
     152    IUFillNumber(&GuideRateN[DEC_AXIS], "GUIDE_RATE_NS", "N/S Rate", "%g", 0, 1, 0.1, 0.3);
     153    IUFillNumberVector(GuideRateNP, GuideRateN, 2, deviceName(), "GUIDE_RATE", "Guiding Rate", MOTION_TAB, IP_RW, 0, IPS_IDLE);
     154
     155    /* Add debug controls so we may debug driver if necessary */
     156    addDebugControl();
     157
     158    return true;
     159}
     160
     161void ScopeSim::ISGetProperties (const char *dev)
     162{
     163    /* First we let our parent populate */
     164    INDI::Telescope::ISGetProperties(dev);
     165
     166    if(isConnected())
     167    {
     168        defineNumber(GuideNSNP);
     169        defineNumber(GuideWENP);
     170        defineNumber(GuideRateNP);
     171        defineNumber(EqPECNV);
     172        defineSwitch(PECErrNSSP);
     173        defineSwitch(PECErrWESP);
     174    }
     175
     176    return;
     177}
     178
     179bool ScopeSim::updateProperties()
     180{
     181    INDI::Telescope::updateProperties();
     182
     183    if (isConnected())
     184    {
     185        defineNumber(GuideNSNP);
     186        defineNumber(GuideWENP);
     187        defineNumber(GuideRateNP);
     188        defineNumber(EqPECNV);
     189        defineSwitch(PECErrNSSP);
     190        defineSwitch(PECErrWESP);
     191
     192    }
     193    else
     194    {
     195        deleteProperty(GuideNSNP->name);
     196        deleteProperty(GuideWENP->name);
     197        deleteProperty(EqPECNV->name);
     198        deleteProperty(PECErrNSSP->name);
     199        deleteProperty(PECErrNSSP->name);
     200        deleteProperty(GuideRateNP->name);
     201    }
     202
     203    return true;
     204}
     205
     206bool ScopeSim::Connect()
     207{
     208    bool rc=false;
     209
     210    if(isConnected()) return true;
     211
     212    rc=Connect(PortT[0].text);
     213
     214    if(rc)
     215        SetTimer(POLLMS);
     216
     217    return rc;
    92218}
    93219
     
    106232    static struct timeval ltv;
    107233    struct timeval tv;
    108     double dt, da, dx;
    109     int nlocked;
     234    double dt=0, da_ra=0, da_dec=0, dx=0, dy=0, ra_guide_dt=0, dec_guide_dt=0;
     235    static double last_dx=0, last_dy=0;
     236    int nlocked, ns_guide_dir=-1, we_guide_dir=-1;
     237    char RA_DISP[64], DEC_DISP[64], RA_GUIDE[64], DEC_GUIDE[64], RA_PEC[64], DEC_PEC[64], RA_TARGET[64], DEC_TARGET[64];
    110238
    111239
     
    118246    dt = tv.tv_sec - ltv.tv_sec + (tv.tv_usec - ltv.tv_usec)/1e6;
    119247    ltv = tv;
    120     da = SLEWRATE*dt;
     248
     249    if ( fabs(targetRA - currentRA)*15. >= GOTO_LIMIT )
     250        da_ra = GOTO_RATE *dt;
     251    else if ( fabs(targetRA - currentRA)*15. >= SLEW_LIMIT )
     252        da_ra = SLEW_RATE *dt;
     253    else
     254        da_ra = FINE_SLEW_RATE *dt;
     255
     256    if ( fabs(targetDEC - currentDEC) >= GOTO_LIMIT )
     257        da_dec = GOTO_RATE *dt;
     258    else if ( fabs(targetDEC - currentDEC) >= SLEW_LIMIT )
     259        da_dec = SLEW_RATE *dt;
     260    else
     261        da_dec = FINE_SLEW_RATE *dt;
     262
     263    switch (MovementNSSP->s)
     264    {
     265       case IPS_BUSY:
     266        if (MovementNSS[MOTION_NORTH].s == ISS_ON)
     267            currentDEC += da_dec;
     268        else if (MovementNSS[MOTION_SOUTH].s == ISS_ON)
     269            currentDEC -= da_dec;
     270
     271        NewRaDec(currentRA, currentDEC);
     272        return true;
     273        break;
     274    }
     275
     276    switch (MovementWESP->s)
     277    {
     278        case IPS_BUSY:
     279
     280        if (MovementWES[MOTION_WEST].s == ISS_ON)
     281            currentRA += da_ra/15.;
     282        else if (MovementWES[MOTION_EAST].s == ISS_ON)
     283            currentRA -= da_ra/15.;
     284
     285        NewRaDec(currentRA, currentDEC);
     286        return true;
     287        break;
     288
     289    }
    121290
    122291    /* Process per current state. We check the state of EQUATORIAL_EOD_COORDS_REQUEST and act acoordingly */
    123292    switch (TrackState)
    124293    {
     294    case SCOPE_IDLE:
     295        EqNV->s = IPS_IDLE;
     296        break;
    125297    case SCOPE_SLEWING:
    126298    case SCOPE_PARKING:
     
    130302        dx = targetRA - currentRA;
    131303
    132         if (fabs(dx) <= da)
     304        if (fabs(dx)*15. <= da_ra)
    133305        {
    134306            currentRA = targetRA;
     
    136308        }
    137309        else if (dx > 0)
    138             currentRA += da/15.;
     310            currentRA += da_ra/15.;
    139311        else
    140             currentRA -= da/15.;
    141 
    142 
    143         dx = targetDEC - currentDEC;
    144         if (fabs(dx) <= da)
     312            currentRA -= da_ra/15.;
     313
     314
     315        dy = targetDEC - currentDEC;
     316        if (fabs(dy) <= da_dec)
    145317        {
    146318            currentDEC = targetDEC;
    147319            nlocked++;
    148320        }
    149         else if (dx > 0)
    150           currentDEC += da;
     321        else if (dy > 0)
     322          currentDEC += da_dec;
    151323        else
    152           currentDEC -= da;
     324          currentDEC -= da_dec;
     325
     326        EqNV->s = IPS_BUSY;
    153327
    154328        if (nlocked == 2)
    155329        {
    156             //eqNP.s = IPS_OK;
    157             //eqNPR.s = IPS_OK;
    158             //IDSetNumber(&eqNP, NULL);
    159             //IDSetNumber(&eqNPR, "Now tracking");
    160330            if (TrackState == SCOPE_SLEWING)
    161331            {
     332
     333                // Initially no PEC in both axis.
     334                EqPECN[0].value = currentRA;
     335                EqPECN[1].value = currentDEC;
     336
     337                IDSetNumber(EqPECNV, NULL);
     338
    162339                TrackState = SCOPE_TRACKING;
     340
     341                EqNV->s = IPS_OK;
    163342                IDMessage(deviceName(), "Telescope slew is complete. Tracking...");
    164343            }
     
    166345            {
    167346                TrackState = SCOPE_PARKED;
     347                EqNV->s = IPS_IDLE;
    168348                IDMessage(deviceName(), "Telescope parked successfully.");
    169349            }
    170350        }
    171         //else
    172           //  IDSetNumber(&eqNP, NULL);
    173351
    174352        break;
     
    176354    case SCOPE_TRACKING:
    177355        /* tracking */
    178         /* RA moves at sidereal, Dec stands still */
    179          currentRA += (SIDRATE*dt/15.);
     356
     357        if (GuideNSN[GUIDE_NORTH].value > 0)
     358        {
     359            if (isDebug())
     360                IDLog("  ****** Commanded to GUIDE NORTH for %g ms *****\n", GuideNSN[GUIDE_NORTH].value*1000);
     361            ns_guide_dir = GUIDE_NORTH;
     362        }
     363        else if (GuideNSN[GUIDE_SOUTH].value > 0)
     364        {
     365            if (isDebug())
     366                IDLog("  ****** Commanded to GUIDE SOUTH for %g ms *****\n", GuideNSN[GUIDE_SOUTH].value*1000);
     367            ns_guide_dir = GUIDE_SOUTH;
     368        }
     369
     370        // WE Guide Selection
     371        if (GuideWEN[GUIDE_WEST].value > 0)
     372        {
     373            we_guide_dir = GUIDE_WEST;
     374            if (isDebug())
     375            IDLog("  ****** Commanded to GUIDE WEST for %g ms ****** \n", GuideWEN[GUIDE_WEST].value*1000);
     376        }
     377        else if (GuideWEN[GUIDE_EAST].value > 0)
     378        {
     379            we_guide_dir = GUIDE_EAST;
     380            if (isDebug())
     381               IDLog(" ****** Commanded to GUIDE EAST for %g ms  ****** \n", GuideWEN[GUIDE_EAST].value*1000);
     382        }
     383
     384        if (ns_guide_dir != -1)
     385        {
     386
     387            dec_guide_dt =  SID_RATE * GuideRateN[DEC_AXIS].value * GuideNSN[ns_guide_dir].value * (ns_guide_dir==GUIDE_NORTH ? 1 : -1);
     388
     389            // If time remaining is more that dt, then decrement and
     390          if (GuideNSN[ns_guide_dir].value >= dt)
     391              GuideNSN[ns_guide_dir].value -= dt;
     392          else             
     393              GuideNSN[ns_guide_dir].value = 0;
     394
     395          EqPECN[DEC_AXIS].value += dec_guide_dt;
     396
     397            if (GuideNSN[ns_guide_dir].value <= 0)
     398            {
     399                GuideNSN[GUIDE_NORTH].value = GuideNSN[GUIDE_SOUTH].value = 0;
     400                GuideNSNP->s = IPS_OK;
     401                IDSetNumber(GuideNSNP, NULL);
     402            }
     403            else
     404                IDSetNumber(GuideNSNP, NULL);
     405          }
     406
     407        if (we_guide_dir != -1)
     408        {
     409
     410            ra_guide_dt = SID_RATE/15.0 * GuideRateN[RA_AXIS].value * GuideWEN[we_guide_dir].value* (we_guide_dir==GUIDE_WEST ? -1 : 1);
     411
     412          if (GuideWEN[we_guide_dir].value >= dt)
     413                GuideWEN[we_guide_dir].value -= dt;
     414          else
     415                GuideWEN[we_guide_dir].value = 0;
     416
     417          EqPECN[RA_AXIS].value += ra_guide_dt;
     418
     419            if (GuideWEN[we_guide_dir].value <= 0)
     420            {
     421                GuideWEN[GUIDE_WEST].value = GuideWEN[GUIDE_EAST].value = 0;
     422                GuideWENP->s = IPS_OK;
     423                IDSetNumber(GuideWENP, NULL);
     424            }
     425            else
     426                IDSetNumber(GuideWENP, NULL);
     427          }
     428
     429
     430        //Mention the followng:
     431        // Current RA displacemet and direction
     432        // Current DEC displacement and direction
     433        // Amount of RA GUIDING correction and direction
     434        // Amount of DEC GUIDING correction and direction
     435
     436        dx = EqPECN[RA_AXIS].value - targetRA;
     437        dy = EqPECN[DEC_AXIS].value - targetDEC;
     438        fs_sexa(RA_DISP, fabs(dx), 2, 3600 );
     439        fs_sexa(DEC_DISP, fabs(dy), 2, 3600 );
     440
     441        fs_sexa(RA_GUIDE, fabs(ra_guide_dt), 2, 3600 );
     442        fs_sexa(DEC_GUIDE, fabs(dec_guide_dt), 2, 3600 );
     443
     444        fs_sexa(RA_PEC, EqPECN[RA_AXIS].value, 2, 3600);
     445        fs_sexa(DEC_PEC, EqPECN[DEC_AXIS].value, 2, 3600);
     446
     447        fs_sexa(RA_TARGET, targetRA, 2, 3600);
     448        fs_sexa(DEC_TARGET, targetDEC, 2, 3600);
     449
     450
     451        if (isDebug() && (dx!=last_dx || dy!=last_dy || ra_guide_dt || dec_guide_dt))
     452        {
     453            last_dx=dx;
     454            last_dy=dy;
     455            IDLog("#########################################\n");
     456            IDLog("dt is %g\n", dt);
     457            IDLog("RA Displacement (%c%s) %s -- %s of target RA %s\n", dx >= 0 ? '+' : '-', RA_DISP, RA_PEC,  (EqPECN[RA_AXIS].value - targetRA) > 0 ? "East" : "West", RA_TARGET);
     458            IDLog("DEC Displacement (%c%s) %s -- %s of target RA %s\n", dy >= 0 ? '+' : '-', DEC_DISP, DEC_PEC, (EqPECN[DEC_AXIS].value - targetDEC) > 0 ? "North" : "South", DEC_TARGET);
     459            IDLog("RA Guide Correction (%g) %s -- Direction %s\n", ra_guide_dt, RA_GUIDE, ra_guide_dt > 0 ? "East" : "West");
     460            IDLog("DEC Guide Correction (%g) %s -- Direction %s\n", dec_guide_dt, DEC_GUIDE, dec_guide_dt > 0 ? "North" : "South");
     461            IDLog("#########################################\n");
     462        }
     463
     464        if (ns_guide_dir != -1 || we_guide_dir != -1)
     465            IDSetNumber(EqPECNV, NULL);
     466
    180467         break;
    181468
     
    200487    Parked=false;
    201488    TrackState = SCOPE_SLEWING;
     489
     490    EqReqNV->s = IPS_BUSY;
     491    EqNV->s    = IPS_BUSY;
     492
    202493    IDMessage(deviceName(), "Slewing to RA: %s - DEC: %s", RAStr, DecStr);
    203494    return true;
     
    214505}
    215506
    216 bool ScopeSim::Connect()
    217 {
    218     //  Parent class is wanting a connection
    219     //IDLog("INDI::Telescope calling connect with %s\n",PortT[0].text);
    220     bool rc=false;
    221 
    222     if(isConnected()) return true;
    223 
    224     //IDLog("Calling Connect\n");
    225 
    226     rc=Connect(PortT[0].text);
    227 
    228     if(rc)
    229         SetTimer(POLLMS);
    230     return rc;
    231 }
    232 
    233 
    234 
    235 /* update the "mount" over time */
    236 void mountSim (void *p)
    237 {
    238 
    239 }
    240 
    241 
     507bool ScopeSim::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
     508{
     509    //  first check if it's for our device
     510
     511    if(strcmp(dev,deviceName())==0)
     512    {
     513        //  This is for our device
     514        //  Now lets see if it's something we process here
     515         if(strcmp(name,"TELESCOPE_TIMED_GUIDE_NS")==0)
     516         {
     517
     518             // Unless we're in track mode, we don't obey guide commands.
     519             if (TrackState != SCOPE_TRACKING)
     520             {
     521                 GuideNSNP->s = IPS_IDLE;
     522                 IDSetNumber(GuideNSNP, NULL);
     523                 return true;
     524             }
     525
     526             IUUpdateNumber(GuideNSNP, values, names, n);
     527
     528           return true;
     529         }
     530
     531         if(strcmp(name,"TELESCOPE_TIMED_GUIDE_WE")==0)
     532         {
     533             // Unless we're in track mode, we don't obey guide commands.
     534             if (TrackState != SCOPE_TRACKING)
     535             {
     536                 GuideWENP->s = IPS_IDLE;
     537                 IDSetNumber(GuideWENP, NULL);
     538                 return true;
     539             }
     540
     541             IUUpdateNumber(GuideWENP, values, names, n);
     542
     543           return true;
     544         }
     545
     546         if(strcmp(name,"GUIDE_RATE")==0)
     547         {
     548             IUUpdateNumber(GuideRateNP, values, names, n);
     549             GuideRateNP->s = IPS_OK;
     550             IDSetNumber(GuideRateNP, NULL);
     551             return true;
     552         }
     553
     554    }
     555
     556    //  if we didn't process it, continue up the chain, let somebody else
     557    //  give it a shot
     558    return INDI::Telescope::ISNewNumber(dev,name,values,names,n);
     559}
     560
     561bool ScopeSim::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
     562{
     563    //IDLog("Enter IsNewSwitch for %s\n",name);
     564    //for(int x=0; x<n; x++) {
     565    //    IDLog("Switch %s %d\n",names[x],states[x]);
     566    //}
     567
     568    if(strcmp(dev,deviceName())==0)
     569    {
     570        if(strcmp(name,"PEC_NS")==0)
     571        {
     572            IUUpdateSwitch(PECErrNSSP,states,names,n);
     573
     574            PECErrNSSP->s = IPS_OK;
     575
     576            if (PECErrNSS[MOTION_NORTH].s == ISS_ON)
     577            {
     578                EqPECN[DEC_AXIS].value += SID_RATE * GuideRateN[DEC_AXIS].value;
     579                if (isDebug())
     580                    IDLog("$$$$$ Simulating PE in NORTH direction for value of %g $$$$$\n", SID_RATE);
     581            }
     582            else
     583            {
     584                EqPECN[DEC_AXIS].value -= SID_RATE * GuideRateN[DEC_AXIS].value;
     585                if (isDebug())
     586                    IDLog("$$$$$ Simulating PE in SOUTH direction for value of %g $$$$$\n", SID_RATE);
     587            }
     588
     589            IUResetSwitch(PECErrNSSP);
     590            IDSetSwitch(PECErrNSSP, NULL);
     591            IDSetNumber(EqPECNV, NULL);
     592
     593            return true;
     594
     595        }
     596
     597        if(strcmp(name,"PEC_WE")==0)
     598        {
     599            IUUpdateSwitch(PECErrWESP,states,names,n);
     600
     601            PECErrWESP->s = IPS_OK;
     602
     603            if (PECErrWES[MOTION_WEST].s == ISS_ON)
     604            {
     605                EqPECN[RA_AXIS].value -= SID_RATE/15. * GuideRateN[RA_AXIS].value;
     606                if (isDebug())
     607                    IDLog("$$$$$ Simulator PE in WEST direction for value of %g $$$$$$\n", SID_RATE);
     608            }
     609            else
     610            {
     611                EqPECN[RA_AXIS].value += SID_RATE/15. * GuideRateN[RA_AXIS].value;
     612                if (isDebug())
     613                    IDLog("$$$$$$ Simulator PE in EAST direction for value of %g $$$$$$\n", SID_RATE);
     614            }
     615
     616            IUResetSwitch(PECErrWESP);
     617            IDSetSwitch(PECErrWESP, NULL);
     618            IDSetNumber(EqPECNV, NULL);
     619
     620            return true;
     621
     622        }
     623
     624    }
     625
     626    //  Nobody has claimed this, so, ignore it
     627    return INDI::Telescope::ISNewSwitch(dev,name,states,names,n);
     628}
     629
     630
     631
     632bool ScopeSim::MoveNS(TelescopeMotionNS dir)
     633{
     634    static int last_motion=-1;
     635
     636    switch (dir)
     637    {
     638      case MOTION_NORTH:
     639        if (last_motion != MOTION_NORTH)
     640            last_motion = MOTION_NORTH;
     641        else
     642        {
     643            IUResetSwitch(MovementNSSP);
     644            MovementNSSP->s = IPS_IDLE;
     645            IDSetSwitch(MovementNSSP, NULL);
     646        }
     647        break;
     648
     649    case MOTION_SOUTH:
     650      if (last_motion != MOTION_SOUTH)
     651          last_motion = MOTION_SOUTH;
     652      else
     653      {
     654          IUResetSwitch(MovementNSSP);
     655          MovementNSSP->s = IPS_IDLE;
     656          IDSetSwitch(MovementNSSP, NULL);
     657      }
     658      break;
     659    }
     660
     661    return true;
     662}
     663
     664bool ScopeSim::MoveWE(TelescopeMotionWE dir)
     665{
     666    static int last_motion=-1;
     667
     668    switch (dir)
     669    {
     670      case MOTION_WEST:
     671        if (last_motion != MOTION_WEST)
     672            last_motion = MOTION_WEST;
     673        else
     674        {
     675            IUResetSwitch(MovementWESP);
     676            MovementWESP->s = IPS_IDLE;
     677            IDSetSwitch(MovementWESP, NULL);
     678        }
     679        break;
     680
     681    case MOTION_EAST:
     682      if (last_motion != MOTION_EAST)
     683          last_motion = MOTION_EAST;
     684      else
     685      {
     686          IUResetSwitch(MovementWESP);
     687          MovementWESP->s = IPS_IDLE;
     688          IDSetSwitch(MovementWESP, NULL);
     689      }
     690      break;
     691    }
     692
     693    return true;
     694
     695}
     696
  • BAORadio/libindi/libindi/drivers/telescope/telescope_simulator.h

    r504 r642  
    1515
    1616        bool Parked;
     17
     18        INumber GuideNSN[2];
     19        INumberVectorProperty *GuideNSNP;
     20
     21
     22        INumber GuideWEN[2];
     23        INumberVectorProperty *GuideWENP;
     24
     25        INumber GuideRateN[2];
     26        INumberVectorProperty *GuideRateNP;
     27
     28        INumberVectorProperty *EqPECNV;
     29        INumber EqPECN[2];
     30
     31        ISwitch PECErrNSS[2];
     32        ISwitchVectorProperty *PECErrNSSP;
     33
     34        ISwitch PECErrWES[2];
     35        ISwitchVectorProperty *PECErrWESP;
     36
     37
    1738    public:
    1839        ScopeSim();
     
    2445        virtual bool Disconnect();
    2546        virtual bool ReadScopeStatus();
     47        virtual bool initProperties();
     48        virtual void ISGetProperties (const char *dev);
     49        virtual bool updateProperties();
     50        virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
     51        virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n);
     52
     53        virtual bool MoveNS(TelescopeMotionNS dir);
     54        virtual bool MoveWE(TelescopeMotionWE dir);
    2655
    2756        bool Goto(double,double);
  • BAORadio/libindi/libindi/drivers/telescope/temmadriver.c

    r490 r642  
    803803
    804804        if((status=portRead(local_buffer,-1,TEMMA_TIMEOUT)==SUCCESS)){
    805                 if(strstr(local_buffer, "stn")==local_buffer){
     805                if( ( (unsigned char *) strstr(local_buffer, "stn"))==local_buffer){
    806806                        local_buffer[7]=0;
    807807                        if (strstr(local_buffer,"on")){ /* stanby on */
  • BAORadio/libindi/libindi/drivers/video/v4ldriver.cpp

    r490 r642  
    565565  int status=0;
    566566
    567  fits_update_key(fptr, TLONG, "EXPOSURE", &(V4LFrame->expose), "Total Exposure Time (ms)", &status);
    568  fits_update_key(fptr, TSTRING, "INSTRUME", v4l_base->getDeviceName(), "Webcam Name", &status);
     567  char keyname[32], comment[64];
     568
     569 strncpy(keyname, "EXPOSURE", 32);
     570 strncpy(comment, "Total Exposure Time (ms)", 64);
     571 fits_update_key(fptr, TLONG, keyname , &(V4LFrame->expose), comment, &status);
     572
     573 strncpy(keyname, "INSTRUME", 32);
     574 strncpy(comment, "Webcam Name", 64);
     575 fits_update_key(fptr, TSTRING, keyname, v4l_base->getDeviceName(), comment, &status);
     576
    569577 fits_write_date(fptr, &status);
    570578}
  • BAORadio/libindi/libindi/eventloop.c

    r490 r642  
    422422        if (ns < 0) {
    423423            perror ("select");
    424             exit(1);
     424            return;
    425425        }
    426426       
     
    480480        if (read (fd, &c, 1) != 1) {
    481481            perror ("read");
    482             exit(1);
     482            return;
    483483        }
    484484
  • BAORadio/libindi/libindi/examples/tutorial_dome.c

    r490 r642  
    4545#define SNOOP_GROUP     "Snooped"
    4646
     47void closeDome();
     48
    4749/* Connect/Disconnect */
    4850static ISwitch PowerS[]                 = {{"CONNECT" , "Connect" , ISS_OFF, 0, 0},{"DISCONNECT", "Disconnect", ISS_ON, 0, 0}};
  • BAORadio/libindi/libindi/examples/tutorial_four.cpp

    r504 r642  
    199199{
    200200        // Ignore if not ours
    201         if (strcmp (dev, deviceID))
     201        if (strcmp (dev, deviceName()))
    202202            return false;
    203203
     
    212212       
    213213        // Ignore if not ours
    214         if (strcmp (dev, deviceID))
     214        if (strcmp (dev, deviceName()))
    215215            return false;
    216216
     
    239239{
    240240        // ignore if not ours //
    241         if (strcmp (dev, deviceID))
     241        if (strcmp (dev, deviceName()))
    242242            return false;
    243243
     
    258258        }*/
    259259
     260    return DefaultDriver::ISNewSwitch(dev, name, states, names, n);
     261
    260262
    261263}
  • BAORadio/libindi/libindi/indiapi.h

    r504 r642  
    4646<ul>
    4747<li><a href="indidevapi_8h.html">INDI Device API</a></li>
     48<li><a href="classINDI_1_1BaseClient.html">INDI Client API</a></li>
     49<li><a href="namespaceINDI.html">INDI Base Drivers</a></li>
    4850<li><a href="indicom_8h.html">INDI Common Routine Library</a></li>
    4951<li><a href="lilxml_8h.html">INDI LilXML Library</a></li>
    5052<li><a href="group__configFunctions.html">Configuration</a></li>
    51 <li><a href="classINDI_1_1BaseClient.html">Client API</a></li>
    5253</ul>
    5354
     
    7576
    7677/* INDI Library version */
    77 #define INDI_LIBV       0.8
     78#define INDI_LIBV       0.9
    7879
    7980/*******************************************************************************
  • BAORadio/libindi/libindi/indidriver.c

    r504 r642  
    236236  {
    237237    np = IUFindNumber(nvp, names[i]);
    238     np->value = values[i];
     238    np->value = values[i]; 
    239239  }
    240240
  • BAORadio/libindi/libindi/indiserver.c

    r504 r642  
    752752    while ( fgets (line, MAXRBUF, fifo.fs) != NULL)
    753753    {
    754         fprintf(stderr, "FIFO: %s\n", line);
     754        if (verbose)
     755            fprintf(stderr, "FIFO: %s\n", line);
    755756
    756757        tDev[0] = '\0', tDriver[0] = '\0', tConfig[0] = '\0', envDev[0] = '\0', envConfig[0] = '\0';
     
    789790                else if (strstr(token, "\"") || strstr(token, "'"))
    790791                {
    791                     strncat(tDev, ++token, MAXRBUF);
     792                    strncat(tDev, ++token, sizeof(tDev)-strlen(tDev)-1);
    792793                    while (token = strsep(&cp, delm) )
    793794                   {
    794795                     strcat(tDev, " ");
    795                      strncat(tDev, token, MAXRBUF);
     796                     strncat(tDev, token, sizeof(tDev)-strlen(tDev)-1);
    796797                     if ( (tp=strchr(tDev, '\"')) || (tp=strchr(tDev, '\'')))
    797798                     {
     
    816817                      if (strstr(token, "\"") || strstr(token, "'"))
    817818                      {
    818                        strncat(tConfig, ++token, MAXRBUF);
     819                       strncat(tConfig, ++token, sizeof(tConfig)-strlen(tDev)-1);
    819820                       while (token = strsep(&cp, delm) )
    820821                       {
    821822                          strcat(tConfig, " ");
    822                           strncat(tConfig, token, MAXRBUF);
     823                          strncat(tConfig, token, sizeof(tConfig)-strlen(tDev)-1);
    823824
    824825                          if ( (tp=strchr(tConfig, '\"')) || (tp=strchr(tConfig, '\'')))
     
    876877                  for (dp = dvrinfo; dp < &dvrinfo[ndvrinfo]; dp++)
    877878                   {
    878                        if (!strcmp(dp->name, tDriver))
     879                       if (!strcmp(dp->name, tDriver) && dp->active==1)
    879880                       {
    880881                           /* If device name is given, check against it before shutting down */
  • BAORadio/libindi/libindi/libindi.pc.cmake

    r501 r642  
    66Name: libindi
    77Description: Instrument Neutral Distributed Interface
    8 URL=http://www.indilib.org/
     8URL: http://www.indilib.org/
    99Version: @CMAKE_INDI_VERSION_STRING@
    10 Libs: -L@LIB_DESTINATION@ -lindi
    11 Cflags: -I@INCLUDE_INSTALL_DIR@ -@INCLUDE_INSTALL_DIR@/libindi
     10Libs: -L${libdir} -lindi
     11Cflags: -I${includedir} -I${includedir}/libindi
    1212
  • BAORadio/libindi/libindi/libs/indibase/baseclient.cpp

    r504 r642  
     1/*******************************************************************************
     2  Copyright(c) 2011 Jasem Mutlaq. All rights reserved.
     3
     4 This library is free software; you can redistribute it and/or
     5 modify it under the terms of the GNU Library General Public
     6 License version 2 as published by the Free Software Foundation.
     7
     8 This library is distributed in the hope that it will be useful,
     9 but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     11 Library General Public License for more details.
     12
     13 You should have received a copy of the GNU Library General Public License
     14 along with this library; see the file COPYING.LIB.  If not, write to
     15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     16 Boston, MA 02110-1301, USA.
     17*******************************************************************************/
     18
    119#include <stdlib.h>
    220#include <string.h>
     
    159177INDI::BaseDriver * INDI::BaseClient::getDriver(const char * deviceName)
    160178{
    161     vector<devicePtr>::const_iterator devi;
     179    vector<INDI::BaseDriver *>::const_iterator devi;
    162180    for ( devi = cDevices.begin(); devi != cDevices.end(); devi++)
    163181        if (!strcmp(deviceName, (*devi)->deviceName()))
    164             return (*devi).get();
     182            return (*devi);
    165183
    166184    return NULL;
     
    170188{
    171189  (static_cast<INDI::BaseClient *> (context))->listenINDI();
     190  return NULL;
    172191}
    173192
     
    291310int INDI::BaseClient::removeDevice( const char * devName, char * errmsg )
    292311{
    293     std::vector<devicePtr>::iterator devicei = cDevices.begin();
    294 
    295     while (devicei != cDevices.end())
     312    std::vector<INDI::BaseDriver *>::iterator devicei;
     313
     314    for (devicei =cDevices.begin(); devicei != cDevices.end();)
    296315    {
    297316      if (strcmp(devName, (*devicei)->deviceName()))
    298317      {
    299           cDevices.erase(devicei);
    300           //delete (*devicei);
     318          delete *devicei;
     319          devicei = cDevices.erase(devicei);
    301320          return 0;
    302321      }
    303 
    304       devicei++;
     322      else
     323          ++devicei;
    305324    }
    306325
     
    312331{
    313332
    314     std::vector<devicePtr>::const_iterator devicei;
     333    std::vector<INDI::BaseDriver *>::const_iterator devicei;
    315334
    316335    for (devicei = cDevices.begin(); devicei != cDevices.end(); devicei++)
    317336    {
    318337        if (!strcmp(devName, (*devicei)->deviceName()))
    319          return (*devicei).get();
     338         return (*devicei);
    320339
    321340    }
     
    328347INDI::BaseDriver * INDI::BaseClient::addDevice (XMLEle *dep, char * errmsg)
    329348{
    330     devicePtr dp(new INDI::BaseDriver());
     349    //devicePtr dp(new INDI::BaseDriver());
     350    INDI::BaseDriver *dp = new INDI::BaseDriver();
    331351    XMLAtt *ap;
    332352    char * device_name;
     
    350370
    351371    /* ok */
    352     return dp.get();
     372    return dp;
    353373}
    354374
  • BAORadio/libindi/libindi/libs/indibase/baseclient.h

    r504 r642  
     1/*******************************************************************************
     2  Copyright(c) 2011 Jasem Mutlaq. All rights reserved.
     3
     4 This library is free software; you can redistribute it and/or
     5 modify it under the terms of the GNU Library General Public
     6 License version 2 as published by the Free Software Foundation.
     7
     8 This library is distributed in the hope that it will be useful,
     9 but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     11 Library General Public License for more details.
     12
     13 You should have received a copy of the GNU Library General Public License
     14 along with this library; see the file COPYING.LIB.  If not, write to
     15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     16 Boston, MA 02110-1301, USA.
     17*******************************************************************************/
     18
    119#ifndef INDIBASECLIENT_H
    220#define INDIBASECLIENT_H
     
    422#include <vector>
    523#include <map>
    6 #include <boost/shared_ptr.hpp>
    724#include <string>
    825
     
    2643   \attention All notifications functions defined in INDI::BaseMediator must be implemented in the client class even if
    2744   they are not used because these are pure virtual functions.
     45
     46   \see <a href=http://indilib.org/index.php?title=Learn_how_to_write_INDI_clients>INDI Client Tutorial</a> for more details.
    2847   \author Jasem Mutlaq
    2948
     
    3352public:
    3453    enum { INDI_DEVICE_NOT_FOUND=-1, INDI_PROPERTY_INVALID=-2, INDI_PROPERTY_DUPLICATED = -3, INDI_DISPATCH_ERROR=-4 };
    35     typedef boost::shared_ptr<INDI::BaseDriver> devicePtr;
     54    //typedef boost::shared_ptr<INDI::BaseDriver> devicePtr;
    3655
    3756    BaseClient();
     
    82101    /** \returns Returns a vector of all devices created in the client.
    83102    */
    84     const vector<devicePtr> & getDrivers() const { return cDevices; }
     103    const vector<INDI::BaseDriver *> & getDrivers() const { return cDevices; }
    85104
    86105    /** \brief Set Binary Large Object policy mode
     
    152171    pthread_t listen_thread;
    153172
    154     vector<devicePtr> cDevices;
     173    vector<INDI::BaseDriver *> cDevices;
    155174    vector<string> cDeviceNames;
    156175
  • BAORadio/libindi/libindi/libs/indibase/basedriver.cpp

    r504 r642  
     1/*******************************************************************************
     2  Copyright(c) 2011 Jasem Mutlaq. All rights reserved.
     3
     4 This library is free software; you can redistribute it and/or
     5 modify it under the terms of the GNU Library General Public
     6 License version 2 as published by the Free Software Foundation.
     7
     8 This library is distributed in the hope that it will be useful,
     9 but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     11 Library General Public License for more details.
     12
     13 You should have received a copy of the GNU Library General Public License
     14 along with this library; see the file COPYING.LIB.  If not, write to
     15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     16 Boston, MA 02110-1301, USA.
     17*******************************************************************************/
     18
    119#include <stdlib.h>
    220#include <string.h>
     
    927#include "base64.h"
    1028
     29PropertyContainer::PropertyContainer()
     30{
     31    pPtr = NULL;
     32    pRegistered = false;
     33    pDynamic = false;
     34    pType = INDI_UNKNOWN;
     35}
     36
     37PropertyContainer::~PropertyContainer()
     38{
     39    // Only delete properties if they were created dynamically via the buildSkeleton
     40    // function. Other drivers are responsible for their own memory allocation.
     41    if (pDynamic)
     42    {
     43        switch (pType)
     44        {
     45        case INDI_NUMBER:
     46         delete ((INumberVectorProperty *) pPtr);
     47         break;
     48
     49        case INDI_TEXT:
     50        delete ((ITextVectorProperty *) pPtr);
     51        break;
     52
     53        case INDI_SWITCH:
     54        delete ((ISwitchVectorProperty *) pPtr);
     55        break;
     56
     57        case INDI_LIGHT:
     58        delete ((ILightVectorProperty *) pPtr);
     59        break;
     60
     61        case INDI_BLOB:
     62        delete ((IBLOBVectorProperty *) pPtr);
     63        break;
     64
     65    }
     66  }
     67}
     68
     69void PropertyContainer::setProperty(void *p)
     70{
     71    pRegistered = true;
     72    pPtr = p;
     73
     74}
     75
     76void PropertyContainer::setType(INDI_TYPE t)
     77{
     78    pType = t;
     79}
     80
     81void PropertyContainer::setRegistered(bool r)
     82{
     83   pRegistered = r;
     84}
     85
     86void PropertyContainer::setDynamic(bool d)
     87{
     88   pDynamic = d;
     89}
     90
    1191INDI::BaseDriver::BaseDriver()
    1292{
    1393    mediator = NULL;
    1494    lp = newLilXML();
     95    char indidev[MAXINDIDEVICE];
     96    strncpy(indidev, "INDIDEV=", MAXINDIDEVICE);
    1597
    1698    if (getenv("INDIDEV") != NULL)
    1799    {
    18         strncpy(deviceID, getenv("INDIDEV"), MAXINDINAME);
    19         putenv("INDIDEV=");
     100        strncpy(deviceID, getenv("INDIDEV"), MAXINDIDEVICE);
     101        putenv(indidev);
    20102    }
    21103}
     
    25107{
    26108    delLilXML (lp);
     109    while(!pAll.empty())
     110    {
     111      delete pAll.back();
     112      pAll.pop_back();
     113    }
    27114}
    28115
     
    31118    INumberVectorProperty * nvp = NULL;
    32119
    33     nvp = static_cast<INumberVectorProperty *> (getProperty(name, INDI_NUMBER));
     120    nvp = static_cast<INumberVectorProperty *> (getProperty(name, PropertyContainer::INDI_NUMBER));
    34121
    35122    return nvp;
     
    40127    ITextVectorProperty * tvp = NULL;
    41128
    42     tvp = static_cast<ITextVectorProperty *> (getProperty(name, INDI_TEXT));
     129    tvp = static_cast<ITextVectorProperty *> (getProperty(name, PropertyContainer::INDI_TEXT));
    43130
    44131    return tvp;
     
    49136    ISwitchVectorProperty * svp = NULL;
    50137
    51     svp = static_cast<ISwitchVectorProperty *> (getProperty(name, INDI_SWITCH));
     138    svp = static_cast<ISwitchVectorProperty *> (getProperty(name, PropertyContainer::INDI_SWITCH));
    52139
    53140    return svp;
     
    58145    ILightVectorProperty * lvp = NULL;
    59146
    60     lvp = static_cast<ILightVectorProperty *> (getProperty(name, INDI_LIGHT));
     147    lvp = static_cast<ILightVectorProperty *> (getProperty(name, PropertyContainer::INDI_LIGHT));
    61148
    62149    return lvp;
     
    67154  IBLOBVectorProperty * bvp = NULL;
    68155
    69   bvp = static_cast<IBLOBVectorProperty *> (getProperty(name, INDI_BLOB));
     156  bvp = static_cast<IBLOBVectorProperty *> (getProperty(name, PropertyContainer::INDI_BLOB));
    70157
    71158  return bvp;
    72159}
    73160
    74 void * INDI::BaseDriver::getProperty(const char *name, INDI_TYPE type)
    75 {
    76     std::map< boost::shared_ptr<void>, INDI_TYPE>::iterator orderi;
     161void * INDI::BaseDriver::getProperty(const char *name, PropertyContainer::INDI_TYPE type)
     162{
     163    PropertyContainer::INDI_TYPE pType;
     164    void *pPtr;
     165    bool pRegistered = false;
     166
     167    std::vector<PropertyContainer *>::iterator orderi;
    77168
    78169    INumberVectorProperty *nvp;
     
    84175    for (orderi = pAll.begin(); orderi != pAll.end(); orderi++)
    85176    {
    86         if (type != INDI_UNKNOWN &&  orderi->second != type)
     177        pType       = (*orderi)->getType();
     178        pPtr        = (*orderi)->getProperty();
     179        pRegistered = (*orderi)->getRegistered();
     180
     181        if (type != PropertyContainer::INDI_UNKNOWN && pType != type)
    87182            continue;
    88183
    89         switch (orderi->second)
    90         {
    91         case INDI_NUMBER:
    92             nvp = static_cast<INumberVectorProperty *>((orderi->first).get());
    93             if (!strcmp(name, nvp->name))
    94                 return (orderi->first).get();
    95              break;
    96         case INDI_TEXT:
    97              tvp = static_cast<ITextVectorProperty *>((orderi->first).get());
    98              if (!strcmp(name, tvp->name))
    99                 return (orderi->first).get();
    100              break;
    101         case INDI_SWITCH:
    102              svp = static_cast<ISwitchVectorProperty *>((orderi->first).get());
    103              if (!strcmp(name, svp->name))
    104                  return (orderi->first).get();
    105              break;
    106         case INDI_LIGHT:
    107              lvp = static_cast<ILightVectorProperty *>((orderi->first).get());
    108              if (!strcmp(name, lvp->name))
    109                  return (orderi->first).get();
    110              break;
    111         case INDI_BLOB:
    112              bvp = static_cast<IBLOBVectorProperty *>((orderi->first).get());
    113              if (!strcmp(name, bvp->name))
    114                  return (orderi->first).get();
     184        switch (pType)
     185        {
     186        case PropertyContainer::INDI_NUMBER:
     187            nvp = static_cast<INumberVectorProperty *>(pPtr);
     188            if (nvp == NULL)
     189                continue;
     190
     191            if (!strcmp(name, nvp->name) && pRegistered)
     192                return pPtr;
     193             break;
     194        case PropertyContainer::INDI_TEXT:
     195             tvp = static_cast<ITextVectorProperty *>(pPtr);
     196             if (tvp == NULL)
     197                 continue;
     198
     199             if (!strcmp(name, tvp->name)  && pRegistered)
     200                return pPtr;
     201             break;
     202        case PropertyContainer::INDI_SWITCH:
     203             svp = static_cast<ISwitchVectorProperty *>(pPtr);
     204             if (svp == NULL)
     205                 continue;
     206
     207             //IDLog("Switch %s and aux value is now %d\n", svp->name, regStatus );
     208             if (!strcmp(name, svp->name) && pRegistered)
     209                 return pPtr;
     210             break;
     211        case PropertyContainer::INDI_LIGHT:
     212             lvp = static_cast<ILightVectorProperty *>(pPtr);
     213             if (lvp == NULL)
     214                 continue;
     215
     216             if (!strcmp(name, lvp->name)  && pRegistered)
     217                 return pPtr;
     218             break;
     219        case PropertyContainer::INDI_BLOB:
     220             bvp = static_cast<IBLOBVectorProperty *>(pPtr);
     221             if (bvp == NULL)
     222                 continue;
     223
     224             if (!strcmp(name, bvp->name) && pRegistered)
     225                 return pPtr;
    115226             break;
    116227        }
     
    121232}
    122233
    123 int INDI::BaseDriver::removeProperty(const char *name)
    124 {
    125     std::map< boost::shared_ptr<void>, INDI_TYPE>::iterator orderi;
     234PropertyContainer * INDI::BaseDriver::getContainer(const char *name, PropertyContainer::INDI_TYPE type)
     235{
     236    PropertyContainer::INDI_TYPE pType;
     237    void *pPtr;
     238    bool pRegistered = false;
     239
     240    std::vector<PropertyContainer *>::iterator orderi;
    126241
    127242    INumberVectorProperty *nvp;
     
    133248    for (orderi = pAll.begin(); orderi != pAll.end(); orderi++)
    134249    {
    135         switch (orderi->second)
    136         {
    137         case INDI_NUMBER:
    138             nvp = static_cast<INumberVectorProperty *>((orderi->first).get());
     250        pType       = (*orderi)->getType();
     251        pPtr        = (*orderi)->getProperty();
     252        pRegistered = (*orderi)->getRegistered();
     253
     254        if (type != PropertyContainer::INDI_UNKNOWN && pType != type)
     255            continue;
     256
     257        switch (pType)
     258        {
     259        case PropertyContainer::INDI_NUMBER:
     260            nvp = static_cast<INumberVectorProperty *>(pPtr);
     261            if (nvp == NULL)
     262                continue;
     263
     264            if (!strcmp(name, nvp->name) && pRegistered)
     265                return *orderi;
     266             break;
     267        case PropertyContainer::INDI_TEXT:
     268             tvp = static_cast<ITextVectorProperty *>(pPtr);
     269             if (tvp == NULL)
     270                 continue;
     271
     272             if (!strcmp(name, tvp->name)  && pRegistered)
     273                return *orderi;
     274             break;
     275        case PropertyContainer::INDI_SWITCH:
     276             svp = static_cast<ISwitchVectorProperty *>(pPtr);
     277             if (svp == NULL)
     278                 continue;
     279
     280             //IDLog("Switch %s and aux value is now %d\n", svp->name, regStatus );
     281             if (!strcmp(name, svp->name) && pRegistered)
     282                 return *orderi;
     283             break;
     284        case PropertyContainer::INDI_LIGHT:
     285             lvp = static_cast<ILightVectorProperty *>(pPtr);
     286             if (lvp == NULL)
     287                 continue;
     288
     289             if (!strcmp(name, lvp->name)  && pRegistered)
     290                 return *orderi;
     291             break;
     292        case PropertyContainer::INDI_BLOB:
     293             bvp = static_cast<IBLOBVectorProperty *>(pPtr);
     294             if (bvp == NULL)
     295                 continue;
     296
     297             if (!strcmp(name, bvp->name) && pRegistered)
     298                 return *orderi;
     299             break;
     300        }
     301
     302    }
     303
     304    return NULL;
     305}
     306
     307int INDI::BaseDriver::removeProperty(const char *name)
     308{   
     309    std::vector<PropertyContainer *>::iterator orderi;
     310
     311    PropertyContainer::INDI_TYPE pType;
     312    void *pPtr;
     313
     314    INumberVectorProperty *nvp;
     315    ITextVectorProperty *tvp;
     316    ISwitchVectorProperty *svp;
     317    ILightVectorProperty *lvp;
     318    IBLOBVectorProperty *bvp;
     319
     320    for (orderi = pAll.begin(); orderi != pAll.end(); orderi++)
     321    {
     322        pType       = (*orderi)->getType();
     323        pPtr        = (*orderi)->getProperty();
     324
     325        switch (pType)
     326        {
     327        case PropertyContainer::INDI_NUMBER:
     328            nvp = static_cast<INumberVectorProperty *>(pPtr);
    139329            if (!strcmp(name, nvp->name))
    140330            {
    141                  pAll.erase(orderi);
     331                (*orderi)->setRegistered(false);
    142332                 return 0;
    143333             }
    144334             break;
    145         case INDI_TEXT:
    146              tvp = static_cast<ITextVectorProperty *>((orderi->first).get());
     335        case PropertyContainer::INDI_TEXT:
     336             tvp = static_cast<ITextVectorProperty *>(pPtr);
    147337             if (!strcmp(name, tvp->name))
    148338             {
    149                   pAll.erase(orderi);
     339                  (*orderi)->setRegistered(false);
    150340                  return 0;
    151341              }
    152342             break;
    153         case INDI_SWITCH:
    154              svp = static_cast<ISwitchVectorProperty *>((orderi->first).get());
     343        case PropertyContainer::INDI_SWITCH:
     344             svp = static_cast<ISwitchVectorProperty *>(pPtr);
    155345             if (!strcmp(name, svp->name))
    156346             {
    157                   pAll.erase(orderi);
     347                 (*orderi)->setRegistered(false);
    158348                  return 0;
    159349              }
    160350             break;
    161         case INDI_LIGHT:
    162              lvp = static_cast<ILightVectorProperty *>((orderi->first).get());
     351        case PropertyContainer::INDI_LIGHT:
     352             lvp = static_cast<ILightVectorProperty *>(pPtr);
    163353             if (!strcmp(name, lvp->name))
    164354             {
    165                   pAll.erase(orderi);
     355                 (*orderi)->setRegistered(false);
    166356                  return 0;
    167357              }
    168358             break;
    169         case INDI_BLOB:
    170              bvp = static_cast<IBLOBVectorProperty *>((orderi->first).get());
     359        case PropertyContainer::INDI_BLOB:
     360             bvp = static_cast<IBLOBVectorProperty *>(pPtr);
    171361             if (!strcmp(name, bvp->name))
    172362             {
    173                   pAll.erase(orderi);
     363                 (*orderi)->setRegistered(false);
    174364                  return 0;
    175365              }
     
    215405    IPerm perm;
    216406    IPState state;
    217     ISRule rule;
    218407    XMLEle *ep = NULL;
    219408    char *rtag, *rname, *rdev;
    220     //INDI_TYPE type;
    221409    double timeout=0;
    222410
     
    258446    if (!strcmp (rtag, "defNumberVector"))
    259447    {
    260 
    261         numberPtr nvp(new INumberVectorProperty);
    262         //INumberVectorProperty *nvp = new INumberVectorProperty;
    263         //INumberVectorProperty *nvp = (INumberVectorProperty *) malloc(sizeof(INumberVectorProperty));
     448        PropertyContainer *indiProp = new PropertyContainer();
     449        INumberVectorProperty *nvp = new INumberVectorProperty;
     450
    264451        INumber *np = NULL;
    265452        int n=0;
     
    281468            np = (INumber *) realloc(np, (n+1) * sizeof(INumber));
    282469
    283             np[n].nvp = nvp.get();
     470            np[n].nvp = nvp;
    284471
    285472            XMLAtt *na = findXMLAtt (ep, "name");
     
    320507        nvp->nnp = n;
    321508        nvp->np  = np;
    322         //orderPtr o(new pOrder);
    323         //o->p = &nvp;
    324         //o->type = INDI_NUMBER;
    325         //pAll.push_back(o);
    326         pAll[nvp] = INDI_NUMBER;
     509
     510        indiProp->setProperty(nvp);
     511        indiProp->setDynamic(true);
     512        indiProp->setType(PropertyContainer::INDI_NUMBER);
     513
     514        pAll.push_back(indiProp);
     515
    327516        //IDLog("Adding number property %s to list.\n", nvp->name);
    328517        if (mediator)
     
    334523  else if (!strcmp (rtag, "defSwitchVector"))
    335524        {
    336             switchPtr svp(new ISwitchVectorProperty);
    337             //ISwitchVectorProperty *svp = new ISwitchVectorProperty;
    338             //ISwitchVectorProperty *svp = (ISwitchVectorProperty *) malloc(sizeof(ISwitchVectorProperty));
     525            PropertyContainer *indiProp = new PropertyContainer();
     526            ISwitchVectorProperty *svp = new ISwitchVectorProperty;
     527
    339528            ISwitch *sp = NULL;
    340529            int n=0;
     
    360549                sp = (ISwitch *) realloc(sp, (n+1) * sizeof(ISwitch));
    361550
    362                 sp[n].svp = svp.get();
     551                sp[n].svp = svp;
    363552
    364553                XMLAtt *na = findXMLAtt (ep, "name");
     
    380569            svp->nsp = n;
    381570            svp->sp  = sp;
    382             //orderPtr o(new pOrder);
    383             //o->p = &svp;
    384             //o->type = INDI_SWITCH;
    385             //pAll.push_back(o);
    386             pAll[svp] = INDI_SWITCH;
     571
     572            indiProp->setProperty(svp);
     573            indiProp->setDynamic(true);
     574            indiProp->setType(PropertyContainer::INDI_SWITCH);
     575
     576            pAll.push_back(indiProp);
    387577            //IDLog("Adding Switch property %s to list.\n", svp->name);
    388578            if (mediator)
     
    396586    {
    397587
    398         //ITextVectorProperty *tvp = new ITextVectorProperty;
    399         //ITextVectorProperty *tvp = (ITextVectorProperty *) malloc(sizeof(ITextVectorProperty));
    400         textPtr tvp(new ITextVectorProperty);
     588        PropertyContainer *indiProp = new PropertyContainer();
     589        ITextVectorProperty *tvp = new ITextVectorProperty;
    401590        IText *tp = NULL;
    402591        int n=0;
     
    418607            tp = (IText *) realloc(tp, (n+1) * sizeof(IText));
    419608
    420             tp[n].tvp = tvp.get();
     609            tp[n].tvp = tvp;
    421610
    422611            XMLAtt *na = findXMLAtt (ep, "name");
     
    439628        tvp->ntp = n;
    440629        tvp->tp  = tp;
    441         //orderPtr o(new pOrder);
    442         //o->p = &tvp;
    443         //o->type = INDI_TEXT;
    444         //pAll.push_back(o);
    445         pAll[tvp] = INDI_TEXT;
     630
     631        indiProp->setProperty(tvp);
     632        indiProp->setDynamic(true);
     633        indiProp->setType(PropertyContainer::INDI_TEXT);
     634
     635        pAll.push_back(indiProp);
    446636        //IDLog("Adding Text property %s to list.\n", tvp->name);
    447637        if (mediator)
     
    454644    {
    455645
    456         //ILightVectorProperty *lvp = new ILightVectorProperty;
    457         //ILightVectorProperty *lvp = (ILightVectorProperty *) malloc(sizeof(ILightVectorProperty));
    458         lightPtr lvp(new ILightVectorProperty);
     646        PropertyContainer *indiProp = new PropertyContainer();
     647        ILightVectorProperty *lvp = new ILightVectorProperty;
    459648        ILight *lp = NULL;
    460649        int n=0;
     
    474663            lp = (ILight *) realloc(lp, (n+1) * sizeof(ILight));
    475664
    476             lp[n].lvp = lvp.get();
     665            lp[n].lvp = lvp;
    477666
    478667            XMLAtt *na = findXMLAtt (ep, "name");
     
    495684        lvp->nlp = n;
    496685        lvp->lp  = lp;
    497         //orderPtr o(new pOrder);
    498         //o->p = &lvp;
    499         //o->type = INDI_LIGHT;
    500         //pAll.push_back(o);
    501         pAll[lvp] = INDI_LIGHT;
     686
     687        indiProp->setProperty(lvp);
     688        indiProp->setDynamic(true);
     689        indiProp->setType(PropertyContainer::INDI_LIGHT);
     690
     691        pAll.push_back(indiProp);
     692
    502693        //IDLog("Adding Light property %s to list.\n", lvp->name);
    503694        if (mediator)
     
    509700else if (!strcmp (rtag, "defBLOBVector"))
    510701    {
    511 
    512         //IBLOBVectorProperty *bvp = new IBLOBVectorProperty;
    513         //IBLOBVectorProperty *bvp = (IBLOBVectorProperty *) malloc(sizeof(IBLOBVectorProperty));
    514         blobPtr bvp(new IBLOBVectorProperty);
     702        PropertyContainer *indiProp = new PropertyContainer();
     703        IBLOBVectorProperty *bvp = new IBLOBVectorProperty;
    515704        IBLOB *bp = NULL;
    516705        int n=0;
     
    530719            bp = (IBLOB *) realloc(bp, (n+1) * sizeof(IBLOB));
    531720
    532             bp[n].bvp = bvp.get();
     721            bp[n].bvp = bvp;
    533722
    534723            XMLAtt *na = findXMLAtt (ep, "name");
     
    560749        bvp->nbp = n;
    561750        bvp->bp  = bp;
    562         //orderPtr o(new pOrder);
    563         //o->p = &bvp;
    564         //o->type = INDI_BLOB;
    565         //pAll.push_back(o);
    566         pAll[bvp] = INDI_BLOB;
     751
     752        indiProp->setProperty(bvp);
     753        indiProp->setDynamic(true);
     754        indiProp->setType(PropertyContainer::INDI_BLOB);
     755
     756        pAll.push_back(indiProp);
    567757        //IDLog("Adding BLOB property %s to list.\n", bvp->name);
    568758        if (mediator)
     
    9131103}
    9141104
    915 void INDI::BaseDriver::registerProperty(void *p, INDI_TYPE type)
    916 {
    917 
    918 
    919     if (type == INDI_NUMBER)
     1105void INDI::BaseDriver::registerProperty(void *p, PropertyContainer::INDI_TYPE type)
     1106{
     1107    PropertyContainer *pContainer;
     1108
     1109    if (type == PropertyContainer::INDI_NUMBER)
    9201110    {
    9211111        INumberVectorProperty *nvp = static_cast<INumberVectorProperty *> (p);
    922         if (getProperty(nvp->name, INDI_NUMBER) != NULL)
     1112        if ( (pContainer = getContainer(nvp->name, PropertyContainer::INDI_NUMBER)) != NULL)
     1113        {
     1114            pContainer->setRegistered(true);
    9231115            return;
    924 
    925         numberPtr ovp(nvp);
    926 
    927         pAll[ovp] = INDI_NUMBER;
    928     }
    929     else if (type == INDI_TEXT)
     1116        }
     1117
     1118        pContainer = new PropertyContainer();
     1119        pContainer->setProperty(p);
     1120        pContainer->setType(type);
     1121
     1122        pAll.push_back(pContainer);
     1123
     1124    }
     1125    else if (type == PropertyContainer::INDI_TEXT)
    9301126    {
    9311127       ITextVectorProperty *tvp = static_cast<ITextVectorProperty *> (p);
    932        if (getProperty(tvp->name, INDI_TEXT) != NULL)
     1128
     1129       if ( (pContainer = getContainer(tvp->name, PropertyContainer::INDI_TEXT)) != NULL)
     1130       {
     1131           pContainer->setRegistered(true);
    9331132           return;
    934 
    935        textPtr ovp(tvp);
    936        //o->p = &ovp;
    937 
    938        pAll[ovp] = INDI_TEXT;
     1133       }
     1134
     1135       pContainer = new PropertyContainer();
     1136       pContainer->setProperty(p);
     1137       pContainer->setType(type);
     1138
     1139       pAll.push_back(pContainer);
     1140
     1141
    9391142   }
    940     else if (type == INDI_SWITCH)
     1143    else if (type == PropertyContainer::INDI_SWITCH)
    9411144    {
    9421145       ISwitchVectorProperty *svp = static_cast<ISwitchVectorProperty *> (p);
    943        if (getProperty(svp->name, INDI_SWITCH) != NULL)
     1146
     1147       if ( (pContainer = getContainer(svp->name, PropertyContainer::INDI_SWITCH)) != NULL)
     1148       {
     1149           pContainer->setRegistered(true);
    9441150           return;
    945 
    946        switchPtr ovp(svp);
    947        //o->p = &ovp;
    948 
    949        IDLog("Registering switch %s\n", svp->name);
    950 
    951        pAll[ovp] = INDI_SWITCH;
    952     }
    953     else if (type == INDI_LIGHT)
     1151       }
     1152
     1153       pContainer = new PropertyContainer();
     1154       pContainer->setProperty(p);
     1155       pContainer->setType(type);
     1156
     1157       pAll.push_back(pContainer);
     1158
     1159    }
     1160    else if (type == PropertyContainer::INDI_LIGHT)
    9541161    {
    9551162       ILightVectorProperty *lvp = static_cast<ILightVectorProperty *> (p);
    956        if (getProperty(lvp->name, INDI_LIGHT) != NULL)
     1163
     1164       if ( (pContainer = getContainer(lvp->name, PropertyContainer::INDI_LIGHT)) != NULL)
     1165       {
     1166           pContainer->setRegistered(true);
    9571167           return;
    958 
    959        lightPtr ovp(lvp);
    960        //o->p = &ovp;
    961        pAll[ovp] = INDI_LIGHT;
     1168       }
     1169
     1170       pContainer = new PropertyContainer();
     1171       pContainer->setProperty(p);
     1172       pContainer->setType(type);
     1173
     1174       pAll.push_back(pContainer);
    9621175   }
    963     else if (type == INDI_BLOB)
     1176    else if (type == PropertyContainer::INDI_BLOB)
    9641177    {
    9651178       IBLOBVectorProperty *bvp = static_cast<IBLOBVectorProperty *> (p);
    966        if (getProperty(bvp->name, INDI_BLOB) != NULL)
     1179
     1180       if ( (pContainer = getContainer(bvp->name, PropertyContainer::INDI_BLOB)) != NULL)
     1181       {
     1182           pContainer->setRegistered(true);
    9671183           return;
    968 
    969        blobPtr ovp(bvp);
    970        //o->p = &ovp;
    971 
    972        pAll[ovp] = INDI_BLOB;
    973     }
    974 
    975 }
    976 
     1184       }
     1185
     1186       pContainer = new PropertyContainer();
     1187       pContainer->setProperty(p);
     1188       pContainer->setType(type);
     1189
     1190       pAll.push_back(pContainer);
     1191
     1192    }
     1193
     1194}
     1195
  • BAORadio/libindi/libindi/libs/indibase/basedriver.h

    r504 r642  
     1/*******************************************************************************
     2  Copyright(c) 2011 Jasem Mutlaq. All rights reserved.
     3
     4 This library is free software; you can redistribute it and/or
     5 modify it under the terms of the GNU Library General Public
     6 License version 2 as published by the Free Software Foundation.
     7
     8 This library is distributed in the hope that it will be useful,
     9 but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     11 Library General Public License for more details.
     12
     13 You should have received a copy of the GNU Library General Public License
     14 along with this library; see the file COPYING.LIB.  If not, write to
     15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     16 Boston, MA 02110-1301, USA.
     17*******************************************************************************/
     18
    119#ifndef INDIBASEDRIVER_H
    220#define INDIBASEDRIVER_H
    321
    4 #include <boost/shared_ptr.hpp>
    5 #include <map>
     22#include <vector>
    623#include <string>
    724
     
    1128
    1229#define MAXRBUF 2048
     30
     31class PropertyContainer
     32{
     33public:
     34    PropertyContainer();
     35    ~PropertyContainer();
     36
     37    /*! INDI property type */
     38    typedef enum
     39    {
     40        INDI_NUMBER, /*!< INumberVectorProperty. */
     41        INDI_SWITCH, /*!< ISwitchVectorProperty. */
     42        INDI_TEXT,   /*!< ITextVectorProperty. */
     43        INDI_LIGHT,  /*!< ILightVectorProperty. */
     44        INDI_BLOB,    /*!< IBLOBVectorProperty. */
     45        INDI_UNKNOWN
     46    } INDI_TYPE;
     47
     48    void setProperty(void *);
     49    void setType(INDI_TYPE t);
     50    void setRegistered(bool r);
     51    void setDynamic(bool d);
     52
     53    void *getProperty() { return pPtr; }
     54    INDI_TYPE getType() { return pType; }
     55    bool getRegistered() { return pRegistered; }
     56    bool getDynamic() { return pDynamic; }
     57
     58private:
     59    void *pPtr;
     60    INDI_TYPE pType;
     61    bool pRegistered;
     62    bool pDynamic;
     63};
    1364
    1465/**
     
    3788    };
    3889
    39     /*! INDI property type */
    40     typedef enum
    41     {
    42         INDI_NUMBER, /*!< INumberVectorProperty. */
    43         INDI_SWITCH, /*!< ISwitchVectorProperty. */
    44         INDI_TEXT,   /*!< ITextVectorProperty. */
    45         INDI_LIGHT,  /*!< ILightVectorProperty. */
    46         INDI_BLOB,    /*!< IBLOBVectorProperty. */
    47         INDI_UNKNOWN
    48     } INDI_TYPE;
    49 
    5090    /** \return Return vector number property given its name */
    5191    INumberVectorProperty * getNumber(const char *name);
     
    5999    IBLOBVectorProperty * getBLOB(const char *name);
    60100
    61     void registerProperty(void *p, INDI_TYPE type);
     101    void registerProperty(void *p, PropertyContainer::INDI_TYPE type);
    62102
    63103    /** \brief Remove a property
     
    77117
    78118    */
    79     void * getProperty(const char *name, INDI_TYPE type = INDI_UNKNOWN);
     119    void * getProperty(const char *name, PropertyContainer::INDI_TYPE type = PropertyContainer::INDI_UNKNOWN);
     120
     121    PropertyContainer * getContainer(const char *name, PropertyContainer::INDI_TYPE type = PropertyContainer::INDI_UNKNOWN);
    80122
    81123    /** \brief Build driver properties from a skeleton file.
     
    133175    int setBLOB(IBLOBVectorProperty *pp, XMLEle * root, char * errmsg);
    134176
    135     char deviceID[MAXINDINAME];
    136 
    137     typedef boost::shared_ptr<INumberVectorProperty> numberPtr;
    138     typedef boost::shared_ptr<ITextVectorProperty> textPtr;
    139     typedef boost::shared_ptr<ISwitchVectorProperty> switchPtr;
    140     typedef boost::shared_ptr<ILightVectorProperty> lightPtr;
    141     typedef boost::shared_ptr<IBLOBVectorProperty> blobPtr;
    142177
    143178private:
    144179
    145     std::map< boost::shared_ptr<void>, INDI_TYPE> pAll;
     180    char deviceID[MAXINDINAME];
     181
     182    std::vector<PropertyContainer *> pAll;
    146183
    147184    LilXML *lp;
  • BAORadio/libindi/libindi/libs/indibase/defaultdriver.cpp

    r504 r642  
     1/*******************************************************************************
     2  Copyright(c) 2011 Jasem Mutlaq. All rights reserved.
     3
     4 This library is free software; you can redistribute it and/or
     5 modify it under the terms of the GNU Library General Public
     6 License version 2 as published by the Free Software Foundation.
     7
     8 This library is distributed in the hope that it will be useful,
     9 but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     11 Library General Public License for more details.
     12
     13 You should have received a copy of the GNU Library General Public License
     14 along with this library; see the file COPYING.LIB.  If not, write to
     15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     16 Boston, MA 02110-1301, USA.
     17*******************************************************************************/
     18
    119#include <stdlib.h>
    220#include <string.h>
     
    826#include "base64.h"
    927
     28const char *COMMUNICATION_TAB = "Communication";
     29const char *MAIN_CONTROL_TAB = "Main Control";
     30const char *MOTION_TAB = "Motion Control";
     31const char *DATETIME_TAB = "Date/Time";
     32const char *SITE_TAB =  "Site Management";
     33const char *OPTIONS_TAB = "Options";
     34const char *FILTER_TAB = "Filter Wheel";
     35const char *GUIDER_TAB = "Guide Wheel";
     36
    1037void timerfunc(void *t)
    1138{
     
    3057    //switchPtr conSw(new ISwitchVectorProperty);
    3158    ConnectionSP = new ISwitchVectorProperty;
     59    DebugSP = NULL;
     60    SimulationSP = NULL;
     61    ConfigProcessSP = NULL;
    3262
    3363    IUFillSwitch(&ConnectionS[0],"CONNECT","Connect",ISS_OFF);
     
    3565    IUFillSwitchVector(ConnectionSP,ConnectionS,2,deviceName(),"CONNECTION","Connection","Main Control",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
    3666
    37     registerProperty(ConnectionSP, INDI_SWITCH);
    38 
     67    registerProperty(ConnectionSP, PropertyContainer::INDI_SWITCH);
     68
     69}
     70
     71INDI::DefaultDriver::~DefaultDriver()
     72{
     73    delete ConnectionSP;
     74    delete DebugSP;
     75    delete SimulationSP;
     76    delete ConfigProcessSP;
    3977}
    4078
     
    4785
    4886   if (pResult)
    49        IDMessage(deviceID, "Configuration successfully loaded.");
     87       IDMessage(deviceID, "Configuration successfully loaded.\n");
     88        else
     89                IDMessage(deviceID,"Error loading configuration\n");
    5090
    5191   IUSaveDefaultConfig(NULL, NULL, deviceID);
     
    5494}
    5595
    56 bool INDI::DefaultDriver::saveConfig()
    57 {
    58     //std::vector<orderPtr>::iterator orderi;
    59 
    60     std::map< boost::shared_ptr<void>, INDI_TYPE>::iterator orderi;
     96bool INDI::DefaultDriver::saveConfigItems(FILE *fp)
     97{
     98    std::vector<PropertyContainer *>::iterator orderi;
     99
     100    PropertyContainer::INDI_TYPE pType;
     101    void *pPtr;
    61102
    62103    ISwitchVectorProperty *svp=NULL;
     
    64105    ITextVectorProperty   *tvp=NULL;
    65106    IBLOBVectorProperty   *bvp=NULL;
    66     char errmsg[MAXRBUF];
    67     FILE *fp = NULL;
    68 
    69     fp = IUGetConfigFP(NULL, deviceID, errmsg);
    70 
    71     if (fp == NULL)
    72     {
    73         IDMessage(deviceID, "Error saving configuration. %s", errmsg);
    74         return false;
    75     }
    76 
    77     IUSaveConfigTag(fp, 0);
    78107
    79108    for (orderi = pAll.begin(); orderi != pAll.end(); orderi++)
    80109    {
    81110
    82         switch (orderi->second)
     111        pType       = (*orderi)->getType();
     112        pPtr        = (*orderi)->getProperty();
     113
     114        switch (pType)
    83115        {
    84         case INDI_NUMBER:
    85              nvp = static_cast<INumberVectorProperty *>((orderi->first).get());
    86              IDLog("Trying to save config for number %s\n", nvp->name);
     116        case PropertyContainer::INDI_NUMBER:
     117             nvp = static_cast<INumberVectorProperty *>(pPtr);
     118             //IDLog("Trying to save config for number %s\n", nvp->name);
    87119             IUSaveConfigNumber(fp, nvp);
    88120             break;
    89         case INDI_TEXT:
    90              tvp = static_cast<ITextVectorProperty *>((orderi->first).get());
     121        case PropertyContainer::INDI_TEXT:
     122             tvp = static_cast<ITextVectorProperty *>(pPtr);
    91123             IUSaveConfigText(fp, tvp);
    92124             break;
    93         case INDI_SWITCH:
    94              svp = static_cast<ISwitchVectorProperty *>((orderi->first).get());
     125        case PropertyContainer::INDI_SWITCH:
     126             svp = static_cast<ISwitchVectorProperty *>(pPtr);
    95127             /* Never save CONNECTION property. Don't save switches with no switches on if the rule is one of many */
    96128             if (!strcmp(svp->name, "CONNECTION") || (svp->r == ISR_1OFMANY && !IUFindOnSwitch(svp)))
     
    98130             IUSaveConfigSwitch(fp, svp);
    99131             break;
    100         case INDI_BLOB:
    101              bvp = static_cast<IBLOBVectorProperty *>((orderi->first).get());
     132        case PropertyContainer::INDI_BLOB:
     133             bvp = static_cast<IBLOBVectorProperty *>(pPtr);
    102134             IUSaveConfigBLOB(fp, bvp);
    103135             break;
    104136        }
    105137    }
     138        return true;
     139}
     140
     141bool INDI::DefaultDriver::saveConfig()
     142{
     143    //std::vector<orderPtr>::iterator orderi;
     144    char errmsg[MAXRBUF];
     145
     146    FILE *fp = NULL;
     147
     148    fp = IUGetConfigFP(NULL, deviceID, errmsg);
     149
     150    if (fp == NULL)
     151    {
     152        IDMessage(deviceID, "Error saving configuration. %s\n", errmsg);
     153        return false;
     154    }
     155
     156    IUSaveConfigTag(fp, 0);
     157
     158        saveConfigItems(fp);
    106159
    107160    IUSaveConfigTag(fp, 1);
     
    142195bool INDI::DefaultDriver::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
    143196{
    144 
    145197    // ignore if not ours //
    146198    if (strcmp (dev, deviceID))
     
    160212        if ( !strcmp(names[i], "CONNECT") && (states[i] == ISS_ON))
    161213        {
     214
    162215            // If not connected, attempt to connect
    163216            if (isConnected() == false)
     
    167220                // If connection is successful, set it thus
    168221                if (rc)
    169                   setConnected(true);
     222                        setConnected(true, IPS_OK);
    170223                else
    171                   setConnected(false, IPS_ALERT);
     224                        setConnected(false, IPS_ALERT);
     225
    172226
    173227                updateProperties();
     
    261315    if (!DebugSP)
    262316    {
    263         switchPtr debSw(new ISwitchVectorProperty);
    264         DebugSP = debSw.get();
     317        DebugSP = new ISwitchVectorProperty;
    265318        IUFillSwitch(&DebugS[0], "ENABLE", "Enable", ISS_OFF);
    266319        IUFillSwitch(&DebugS[1], "DISABLE", "Disable", ISS_ON);
    267         IUFillSwitchVector(DebugSP, DebugS, NARRAY(DebugS), deviceID, "DEBUG", "Debug", "Options", IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
    268         pAll[debSw] = INDI_SWITCH;
     320        IUFillSwitchVector(DebugSP, DebugS, NARRAY(DebugS), deviceName(), "DEBUG", "Debug", "Options", IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
     321        registerProperty(DebugSP, PropertyContainer::INDI_SWITCH);
    269322    }
    270323    else
     
    285338    if (!SimulationSP)
    286339    {
    287         switchPtr simSw(new ISwitchVectorProperty);
    288         SimulationSP = simSw.get();
     340        SimulationSP = new ISwitchVectorProperty;
    289341        IUFillSwitch(&SimulationS[0], "ENABLE", "Enable", ISS_OFF);
    290342        IUFillSwitch(&SimulationS[1], "DISABLE", "Disable", ISS_ON);
    291         IUFillSwitchVector(SimulationSP, SimulationS, NARRAY(SimulationS), deviceID, "SIMULATION", "Simulation", "Options", IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
    292         pAll[simSw] = INDI_SWITCH;
     343        IUFillSwitchVector(SimulationSP, SimulationS, NARRAY(SimulationS), deviceName(), "SIMULATION", "Simulation", "Options", IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
     344        registerProperty(SimulationSP, PropertyContainer::INDI_SWITCH);
    293345    }
    294346    else
     
    307359    if (!ConfigProcessSP)
    308360    {
    309         switchPtr configSw(new ISwitchVectorProperty);
    310         ConfigProcessSP = configSw.get();
     361        ConfigProcessSP = new ISwitchVectorProperty;
    311362        IUFillSwitch(&ConfigProcessS[0], "CONFIG_LOAD", "Load", ISS_OFF);
    312363        IUFillSwitch(&ConfigProcessS[1], "CONFIG_SAVE", "Save", ISS_OFF);
    313364        IUFillSwitch(&ConfigProcessS[2], "CONFIG_DEFAULT", "Default", ISS_OFF);
    314         IUFillSwitchVector(ConfigProcessSP, ConfigProcessS, NARRAY(ConfigProcessS), deviceID, "CONFIG_PROCESS", "Configuration", "Options", IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
    315         pAll[configSw] = INDI_SWITCH;
     365        IUFillSwitchVector(ConfigProcessSP, ConfigProcessS, NARRAY(ConfigProcessS), deviceName(), "CONFIG_PROCESS", "Configuration", "Options", IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
     366        registerProperty(ConfigProcessSP, PropertyContainer::INDI_SWITCH);
    316367    }
    317368    /**************************************************************************/
     
    416467void INDI::DefaultDriver::ISGetProperties (const char *dev)
    417468{
    418     std::map< boost::shared_ptr<void>, INDI_TYPE>::iterator orderi;
     469    std::vector<PropertyContainer *>::iterator orderi;
    419470    static int isInit = 0;
    420 
    421     //fprintf(stderr,"Enter ISGetProperties '%s'\n",dev);
     471    PropertyContainer::INDI_TYPE pType;
     472    void *pPtr;
     473
    422474    if(isInit == 0)
    423475    {
     
    442494    for (orderi = pAll.begin(); orderi != pAll.end(); orderi++)
    443495    {
    444         switch (orderi->second)
     496        pType       = (*orderi)->getType();
     497        pPtr        = (*orderi)->getProperty();
     498
     499        switch (pType)
    445500        {
    446         case INDI_NUMBER:
    447              IDDefNumber(static_cast<INumberVectorProperty *>((orderi->first).get()) , NULL);
    448              break;
    449         case INDI_TEXT:
    450              IDDefText(static_cast<ITextVectorProperty *>((orderi->first).get()) , NULL);
    451              break;
    452         case INDI_SWITCH:
    453              IDDefSwitch(static_cast<ISwitchVectorProperty *>((orderi->first).get()) , NULL);
    454              break;
    455         case INDI_LIGHT:
    456              IDDefLight(static_cast<ILightVectorProperty *>((orderi->first).get()) , NULL);
    457              break;
    458         case INDI_BLOB:
    459              IDDefBLOB(static_cast<IBLOBVectorProperty *>((orderi->first).get()) , NULL);
     501        case PropertyContainer::INDI_NUMBER:
     502             IDDefNumber(static_cast<INumberVectorProperty *>(pPtr) , NULL);
     503             break;
     504        case PropertyContainer::INDI_TEXT:
     505             IDDefText(static_cast<ITextVectorProperty *>(pPtr) , NULL);
     506             break;
     507        case PropertyContainer::INDI_SWITCH:
     508             IDDefSwitch(static_cast<ISwitchVectorProperty *>(pPtr) , NULL);
     509             break;
     510        case PropertyContainer::INDI_LIGHT:
     511             IDDefLight(static_cast<ILightVectorProperty *>(pPtr) , NULL);
     512             break;
     513        case PropertyContainer::INDI_BLOB:
     514             IDDefBLOB(static_cast<IBLOBVectorProperty *>(pPtr) , NULL);
    460515             break;
    461516        }
     
    535590//  This is a helper function
    536591//  that just encapsulates the Indi way into our clean c++ way of doing things
    537 int INDI::DefaultDriver::SetTimer(int t)
    538 {
    539     return IEAddTimer(t,timerfunc,this);
     592int INDI::DefaultDriver::SetTimer(int ms)
     593{
     594    return IEAddTimer(ms,timerfunc,this);
    540595}
    541596
    542597//  Just another helper to help encapsulate indi into a clean class
    543 void INDI::DefaultDriver::RemoveTimer(int t)
    544 {
    545     IERmTimer(t);
     598void INDI::DefaultDriver::RemoveTimer(int id)
     599{
     600    IERmTimer(id);
    546601    return;
    547602}
     
    577632void INDI::DefaultDriver::defineNumber(INumberVectorProperty *nvp)
    578633{
    579     registerProperty(nvp, INDI_NUMBER);
     634    registerProperty(nvp, PropertyContainer::INDI_NUMBER);
    580635    IDDefNumber(nvp, NULL);
    581636}
     
    583638void INDI::DefaultDriver::defineText(ITextVectorProperty *tvp)
    584639{
    585     registerProperty(tvp, INDI_TEXT);
     640    registerProperty(tvp, PropertyContainer::INDI_TEXT);
    586641    IDDefText(tvp, NULL);
    587642}
     
    589644void INDI::DefaultDriver::defineSwitch(ISwitchVectorProperty *svp)
    590645{
    591     registerProperty(svp, INDI_SWITCH);
     646    registerProperty(svp, PropertyContainer::INDI_SWITCH);
    592647    IDDefSwitch(svp, NULL);
    593648}
     
    595650void INDI::DefaultDriver::defineLight(ILightVectorProperty *lvp)
    596651{
    597     registerProperty(lvp, INDI_LIGHT);
     652    registerProperty(lvp, PropertyContainer::INDI_LIGHT);
    598653    IDDefLight(lvp, NULL);
    599654}
     
    601656void INDI::DefaultDriver::defineBLOB(IBLOBVectorProperty *bvp)
    602657{
    603     registerProperty(bvp, INDI_BLOB);
     658    registerProperty(bvp, PropertyContainer::INDI_BLOB);
    604659    IDDefBLOB(bvp, NULL);
    605660}
  • BAORadio/libindi/libindi/libs/indibase/defaultdriver.h

    r504 r642  
     1/*******************************************************************************
     2  Copyright(c) 2011 Jasem Mutlaq. All rights reserved.
     3
     4 This library is free software; you can redistribute it and/or
     5 modify it under the terms of the GNU Library General Public
     6 License version 2 as published by the Free Software Foundation.
     7
     8 This library is distributed in the hope that it will be useful,
     9 but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     11 Library General Public License for more details.
     12
     13 You should have received a copy of the GNU Library General Public License
     14 along with this library; see the file COPYING.LIB.  If not, write to
     15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     16 Boston, MA 02110-1301, USA.
     17*******************************************************************************/
     18
    119#ifndef INDIDEFAULTDRIVER_H
    220#define INDIDEFAULTDRIVER_H
     
    523#include "indidriver.h"
    624
     25#include <auto_ptr.h>
     26
     27extern const char *COMMUNICATION_TAB;
     28extern const char *MAIN_CONTROL_TAB;
     29extern const char *MOTION_TAB;
     30extern const char *DATETIME_TAB;
     31extern const char *SITE_TAB;
     32extern const char *OPTIONS_TAB;
     33extern const char *FILTER_TAB;
     34extern const char *GUIDER_TAB;
     35
    736/**
    837 * \class INDI::DefaultDriver
    9    \brief Class to provide extended functionary for drivers in addition
     38   \brief Class to provide extended functionality for drivers in addition
    1039to the functionality provided by INDI::BaseDriver. This class should \e only be subclassed by
    1140drivers directly as it is linked with main(). Virtual drivers cannot employ INDI::DefaultDriver.
     
    2150public:
    2251    DefaultDriver();
    23     virtual ~DefaultDriver() {}
     52    virtual ~DefaultDriver();
    2453
    2554    /** \brief Add Debug, Simulation, and Configuration options to the driver */
     
    74103    virtual bool deleteProperty(const char *propertyName);
    75104
    76     /** \brief Connect or Disconnect a device.
     105
     106    /** \brief Set connection switch status in the client.
    77107      \param status If true, the driver will attempt to connect to the device (CONNECT=ON). If false, it will attempt
    78108to disconnect the device.
    79       \param msg A message to be sent along with connect/disconnect command.
     109      \param status True to set CONNECT on, false to set DISCONNECT on.
     110      \param state State of CONNECTION properti, by default IPS_OK.
     111      \param msg A message to be sent along with connect/disconnect command, by default NULL.
    80112    */
    81113    virtual void setConnected(bool status, IPState state=IPS_OK, const char *msg = NULL);
    82114
    83     int SetTimer(int);
    84     void RemoveTimer(int);
     115    /** \brief Set a timer to call the function TimerHit after ms milliseconds
     116        \param ms timer duration in milliseconds.
     117        \return id of the timer to be used with RemoveTimer
     118   */
     119    int SetTimer(int ms);
     120
     121    /** \brief Remove timer added with SetTimer
     122        \param id ID of the timer as returned from SetTimer
     123   */
     124    void RemoveTimer(int id);
     125
     126    /** \brief Callback function to be called once SetTimer duration elapses. */
    85127    virtual void TimerHit();
    86128
     
    116158        \return True if successful, false otherwise.
    117159    */
    118     bool loadConfig();
     160    virtual bool loadConfig();
    119161
    120162    /** \brief Save the current properties in a configuration file
    121163        \return True if successful, false otherwise.
    122164    */
    123     bool saveConfig();
     165    virtual bool saveConfig();
     166    virtual bool saveConfigItems(FILE *fp);
    124167
    125168    /** \brief Load the default configuration file
    126169        \return True if successful, false otherwise.
    127170    */
    128     bool loadDefaultConfig();
     171    virtual bool loadDefaultConfig();
     172
    129173
    130174    // Simulatin & Debug
  • BAORadio/libindi/libindi/libs/indibase/indibase.h

    r504 r642  
    99/**
    1010 * \namespace INDI
    11    \brief Namespace to encapsulate INDI client, device, and mediator classes
     11   \brief Namespace to encapsulate INDI client, drivers, and mediator classes.
     12   Developers can subclass the base devices class to implement device specific functionality. This ensures interoperability and consistency among devices within the same family
     13   and reduces code overhead.
    1214
    1315   <ul>
     
    1820   <li>DefaultDriver: INDI::BaseDriver with extended functionality such as debug, simulation, and configuration support.
    1921       It is \e only used by drivers directly, it cannot be used by clients.</li>
     22   <li>FilterInterface: Basic interface for filter wheels functions.</li>
     23   <li>GuiderInterface: Basic interface for guider (ST4) port functions.</li>
     24   <li>CCD: Base class for CCD drivers. Provides basic support for single chip CCD and CCDs with a guide head as well.</li>
     25   <li>Telescope: Base class for telescope drivers.</li>
     26   <li>FilterWheel: Base class for Filter Wheels. It implements the FilterInterface.</li>
     27   <li>Focuser: Base class for focusers.</li>
     28   <li>USBDevice: Base class for USB devices for direct read/write/control over USB.</li>
    2029   </ul>
    2130 */
     
    2635    class BaseDriver;
    2736    class DefaultDriver;
     37    class FilterInterface;
     38    class GuiderInterface;
    2839    class CCD;
    2940    class Telescope;
    3041    class FilterWheel;
    3142    class Focuser;
    32     class USBDevice;
     43    class USBDevice;   
    3344}
    3445
  • BAORadio/libindi/libindi/libs/indibase/indiccd.cpp

    r504 r642  
    11/*******************************************************************************
    2   Copyright(c) 2010 Gerry Rozema. All rights reserved.
    3 
    4   This program is free software; you can redistribute it and/or modify it
    5   under the terms of the GNU General Public License as published by the Free
    6   Software Foundation; either version 2 of the License, or (at your option)
    7   any later version.
    8 
    9   This program is distributed in the hope that it will be useful, but WITHOUT
    10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    12   more details.
    13 
    14   You should have received a copy of the GNU General Public License along with
    15   this program; if not, write to the Free Software Foundation, Inc., 59
    16   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    17 
    18   The full GNU General Public License is included in this distribution in the
    19   file called LICENSE.
     2  Copyright(c) 2010, 2011 Gerry Rozema, Jasem Mutlaq. All rights reserved.
     3
     4 This library is free software; you can redistribute it and/or
     5 modify it under the terms of the GNU Library General Public
     6 License version 2 as published by the Free Software Foundation.
     7
     8 This library is distributed in the hope that it will be useful,
     9 but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     11 Library General Public License for more details.
     12
     13 You should have received a copy of the GNU Library General Public License
     14 along with this library; see the file COPYING.LIB.  If not, write to
     15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     16 Boston, MA 02110-1301, USA.
    2017*******************************************************************************/
    2118
     
    2421#include <string.h>
    2522
    26 #include <fitsio.h>
    2723#include <zlib.h>
    2824
     25const char *IMAGE_SETTINGS_TAB = "Image Settings";
     26const char *IMAGE_INFO_TAB     = "Image Info";
     27const char *GUIDE_HEAD_TAB     = "Guide Head";
     28const char *GUIDE_CONTROL_TAB     = "Guider Control";
     29
     30CCDChip::CCDChip()
     31{
     32    SendCompressed=false;
     33    Interlaced=false;
     34
     35    RawFrame=NULL;
     36    RawFrameSize=0;
     37
     38    FrameType=LIGHT_FRAME;
     39
     40    ImageFrameNP = new INumberVectorProperty;
     41    FrameTypeSP = new ISwitchVectorProperty;
     42    ImageExposureNP = new INumberVectorProperty;
     43    ImageBinNP = new INumberVectorProperty;
     44    ImagePixelSizeNP = new INumberVectorProperty;
     45    CompressSP = new ISwitchVectorProperty;
     46    FitsBP = new IBLOBVectorProperty;
     47
     48}
     49
     50CCDChip::~CCDChip()
     51{
     52    delete RawFrame;
     53    RawFrameSize=0;
     54    RawFrame=NULL;
     55
     56    delete ImageFrameNP;
     57    delete FrameTypeSP;
     58    delete ImageExposureNP;
     59    delete ImageBinNP;
     60    delete ImagePixelSizeNP;
     61    delete CompressSP;
     62    delete FitsBP;
     63}
     64
     65int CCDChip::setFrameType(CCD_FRAME t)
     66{
     67    //fprintf(stderr,"Set frame type to %d\n",t);
     68    FrameType=t;
     69    return 0;
     70}
     71
     72void CCDChip::setResolutoin(int x, int y)
     73{
     74    XRes = x;
     75    YRes = y;
     76
     77    ImagePixelSizeN[0].value=x;
     78    ImagePixelSizeN[1].value=y;
     79
     80    IDSetNumber(ImagePixelSizeNP, NULL);
     81}
     82
     83void CCDChip::setFrame(int subx, int suby, int subw, int subh)
     84{
     85    SubX = subx;
     86    SubY = suby;
     87    SubW = subw;
     88    SubH = subh;
     89
     90    ImageFrameN[0].value = SubX;
     91    ImageFrameN[1].value = SubY;
     92    ImageFrameN[2].value = SubW;
     93    ImageFrameN[3].value = SubH;
     94
     95    IDSetNumber(ImageFrameNP, NULL);
     96}
     97
     98void CCDChip::setBin(int hor, int ver)
     99{
     100    BinX = hor;
     101    BinY = ver;
     102
     103    ImageBinN[0].value = BinX;
     104    ImageBinN[1].value = BinY;
     105
     106    IDSetNumber(ImageBinNP, NULL);
     107}
     108
     109void CCDChip::setPixelSize(int x, int y)
     110{
     111    PixelSizex = x;
     112    PixelSizey = y;
     113
     114    ImagePixelSizeN[2].value=x;
     115    ImagePixelSizeN[3].value=x;
     116    ImagePixelSizeN[4].value=y;
     117
     118    IDSetNumber(ImagePixelSizeNP, NULL);
     119
     120}
     121
     122void CCDChip::setBPP(int bbp)
     123{
     124    BPP = bbp;
     125
     126    ImagePixelSizeN[5].value = BPP;
     127
     128    IDSetNumber(ImagePixelSizeNP, NULL);
     129}
     130
     131void CCDChip::setFrameBufferSize(int nbuf)
     132{
     133    if (RawFrame != NULL)
     134        delete RawFrame;
     135
     136    RawFrameSize = nbuf;
     137
     138    RawFrame = new char[nbuf];
     139}
     140
     141void CCDChip::setExposure(double duration)
     142{
     143    ImageExposureN[0].value = duration;
     144    IDSetNumber(ImageExposureNP, NULL);
     145}
     146
     147void CCDChip::setInterlaced(bool intr)
     148{
     149    Interlaced = intr;
     150}
     151
     152void CCDChip::setExposureFailed()
     153{
     154    ImageExposureNP->s = IPS_ALERT;
     155    IDSetNumber(ImageExposureNP, NULL);
     156}
     157
    29158INDI::CCD::CCD()
    30159{
    31160    //ctor
    32     SendCompressed=false;
    33     GuiderCompressed=false;
    34161    HasGuideHead=false;
    35162    HasSt4Port=false;
    36 
    37     RawFrame=NULL;
    38     RawFrameSize=0;
    39 
    40     RawGuideSize=0;
    41     RawGuiderFrame=NULL;
    42 
    43     FrameType=FRAME_TYPE_LIGHT;
    44 
     163    InExposure=false;
     164    TelescopeTP = new ITextVectorProperty;
    45165}
    46166
    47167INDI::CCD::~CCD()
    48168{
    49     //dtor
     169    delete TelescopeTP;
    50170}
    51171
    52172bool INDI::CCD::initProperties()
    53173{
    54     //IDLog("INDI::CCD initProperties '%s'\n",deviceName());
    55 
    56174    DefaultDriver::initProperties();   //  let the base class flesh in what it wants
    57175
    58     //IDLog("INDI::CCD::initProperties()\n");
    59     IUFillNumber(&ImageFrameN[0],"X","Left ","%4.0f",0,1392.0,0,0);
    60     IUFillNumber(&ImageFrameN[1],"Y","Top","%4.0f",0,1040,0,0);
    61     IUFillNumber(&ImageFrameN[2],"WIDTH","Width","%4.0f",0,1392.0,0,1392.0);
    62     IUFillNumber(&ImageFrameN[3],"HEIGHT","Height","%4.0f",0,1040,0,1040);
    63     IUFillNumberVector(&ImageFrameNV,ImageFrameN,4,deviceName(),"CCD_FRAME","Frame","Image Settings",IP_RW,60,IPS_IDLE);
    64 
    65     IUFillSwitch(&FrameTypeS[0],"FRAME_LIGHT","Light",ISS_ON);
    66     IUFillSwitch(&FrameTypeS[1],"FRAME_BIAS","Bias",ISS_OFF);
    67     IUFillSwitch(&FrameTypeS[2],"FRAME_DARK","Dark",ISS_OFF);
    68     IUFillSwitch(&FrameTypeS[3],"FRAME_FLAT","Flat",ISS_OFF);
    69     IUFillSwitchVector(&FrameTypeSV,FrameTypeS,4,deviceName(),"CCD_FRAME_TYPE","FrameType","Image Settings",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
    70 
    71     IUFillNumber(&ImageExposureN[0],"CCD_EXPOSURE_VALUE","Duration (s)","%5.2f",0,36000,0,1.0);
    72     IUFillNumberVector(&ImageExposureNV,ImageExposureN,1,deviceName(),"CCD_EXPOSURE","Expose","Main Control",IP_RW,60,IPS_IDLE);
    73     //IUFillNumber(&CcdExposureReqN[0],"CCD_EXPOSURE_VALUE","Duration","%5.2f",0,36000,0,1.0);
    74     //IUFillNumberVector(&CcdExposureReqNV,CcdExposureReqN,1,deviceName(),"CCD_EXPOSURE_REQUEST","Expose","Main Control",IP_WO,60,IPS_IDLE);
    75 
    76     IUFillNumber(&ImageBinN[0],"HOR_BIN","X","%2.0f",1,4,1,1);
    77     IUFillNumber(&ImageBinN[1],"VER_BIN","Y","%2.0f",1,4,1,1);
    78     IUFillNumberVector(&ImageBinNV,ImageBinN,2,deviceName(),"CCD_BINNING","Binning","Image Settings",IP_RW,60,IPS_IDLE);
    79 
    80     IUFillNumber(&ImagePixelSizeN[0],"CCD_MAX_X","Resolution x","%4.0f",1,40,0,6.45);
    81     IUFillNumber(&ImagePixelSizeN[1],"CCD_MAX_Y","Resolution y","%4.0f",1,40,0,6.45);
    82     IUFillNumber(&ImagePixelSizeN[2],"CCD_PIXEL_SIZE","Pixel size (um)","%5.2f",1,40,0,6.45);
    83     IUFillNumber(&ImagePixelSizeN[3],"CCD_PIXEL_SIZE_X","Pixel size X","%5.2f",1,40,0,6.45);
    84     IUFillNumber(&ImagePixelSizeN[4],"CCD_PIXEL_SIZE_Y","Pixel size Y","%5.2f",1,40,0,6.45);
    85     IUFillNumber(&ImagePixelSizeN[5],"CCD_BITSPERPIXEL","Bits per pixel","%3.0f",1,40,0,6.45);
    86     IUFillNumberVector(&ImagePixelSizeNV,ImagePixelSizeN,6,deviceName(),"CCD_INFO","Ccd Information","Image Info",IP_RO,60,IPS_IDLE);
    87 
    88 
    89 
    90     IUFillNumber(&GuiderFrameN[0],"X","Left ","%4.0f",0,1392.0,0,0);
    91     IUFillNumber(&GuiderFrameN[1],"Y","Top","%4.0f",0,1040,0,0);
    92     IUFillNumber(&GuiderFrameN[2],"WIDTH","Width","%4.0f",0,1392.0,0,1392.0);
    93     IUFillNumber(&GuiderFrameN[3],"HEIGHT","Height","%4.0f",0,1040,0,1040);
    94     IUFillNumberVector(&GuiderFrameNV,GuiderFrameN,4,deviceName(),"GUIDER_FRAME","Frame","Guidehead Settings",IP_RW,60,IPS_IDLE);
    95 
    96 
    97     IUFillNumber(&GuiderPixelSizeN[0],"GUIDER_MAX_X","Resolution x","%4.0f",1,40,0,6.45);
    98     IUFillNumber(&GuiderPixelSizeN[1],"GUIDER_MAX_Y","Resolution y","%4.0f",1,40,0,6.45);
    99     IUFillNumber(&GuiderPixelSizeN[2],"GUIDER_PIXEL_SIZE","Pixel size (um)","%5.2f",1,40,0,6.45);
    100     IUFillNumber(&GuiderPixelSizeN[3],"GUIDER_PIXEL_SIZE_X","Pixel size X","%5.2f",1,40,0,6.45);
    101     IUFillNumber(&GuiderPixelSizeN[4],"GUIDER_PIXEL_SIZE_Y","Pixel size Y","%5.2f",1,40,0,6.45);
    102     IUFillNumber(&GuiderPixelSizeN[5],"GUIDER_BITSPERPIXEL","Bits per pixel","%3.0f",1,40,0,6.45);
    103     IUFillNumberVector(&GuiderPixelSizeNV,GuiderPixelSizeN,6,deviceName(),"GUIDER_INFO","Guidehead Information","Guidehead Info",IP_RO,60,IPS_IDLE);
    104 
    105 
    106     IUFillNumber(&GuiderExposureN[0],"GUIDER_EXPOSURE_VALUE","Duration (s)","%5.2f",0,36000,0,1.0);
    107     IUFillNumberVector(&GuiderExposureNV,GuiderExposureN,1,deviceName(),"GUIDER_EXPOSURE","Guider","Main Cntrol",IP_RW,60,IPS_IDLE);
    108 
    109 
    110     IUFillSwitch(&GuiderVideoS[0],"ON","on",ISS_OFF);
    111     IUFillSwitch(&GuiderVideoS[1],"OFF","off",ISS_OFF);
    112     IUFillSwitchVector(&GuiderVideoSV,GuiderVideoS,2,deviceName(),"VIDEO_STREAM","Guider Stream","Guidehead Settings",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
    113 
    114     //IDLog("Setting up blob\n");
    115 
    116     IUFillSwitch(&CompressS[0],"COMPRESS","Compress",ISS_OFF);
    117     IUFillSwitch(&CompressS[1],"RAW","Raw",ISS_ON);
    118     IUFillSwitchVector(&CompressSV,CompressS,2,deviceName(),"COMPRESSION","Image","Data Channel",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
    119 
    120     IUFillSwitch(&GuiderCompressS[0],"GCOMPRESS","Compress",ISS_OFF);
    121     IUFillSwitch(&GuiderCompressS[1],"GRAW","Raw",ISS_ON);
    122     IUFillSwitchVector(&GuiderCompressSV,GuiderCompressS,2,deviceName(),"GCOMPRESSION","Guider","Data Channel",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
    123 
    124     IUFillBLOB(&FitsB,"CCD1","Image","");
    125     IUFillBLOBVector(&FitsBV,&FitsB,1,deviceName(),"CCD1","Image Data","Data Channel",IP_RO,60,IPS_IDLE);
    126 
    127     IUFillBLOB(&GuiderB,"CCD2","Guider","");
    128     IUFillBLOBVector(&GuiderBV,&GuiderB,1,deviceName(),"CCD2","Guider Data","Data Channel",IP_RO,60,IPS_IDLE);
    129 
    130     IUFillNumber(&GuideNS[0],"TIMED_GUIDE_N","North (sec)","%g",0,10,0.001,0);
    131     IUFillNumber(&GuideNS[1],"TIMED_GUIDE_S","South (sec)","%g",0,10,0.001,0);
    132     IUFillNumberVector(&GuideNSV,GuideNS,2,deviceName(),"TELESCOPE_TIMED_GUIDE_NS","Guide North/South","GuiderControl",IP_RW,60,IPS_IDLE);
    133 
    134     IUFillNumber(&GuideEW[0],"TIMED_GUIDE_E","East (sec)","%g",0,10,0.001,0);
    135     IUFillNumber(&GuideEW[1],"TIMED_GUIDE_W","West (sec)","%g",0,10,0.001,0);
    136     IUFillNumberVector(&GuideEWV,GuideEW,2,deviceName(),"TELESCOPE_TIMED_GUIDE_WE","Guide East/West","GuiderControl",IP_RW,60,IPS_IDLE);
    137 
    138 
    139     //IDLog("Setting up ccdpreview stuff\n");
    140     //IUFillNumber(&GuiderN[0],"WIDTH","Width","%4.0f",0.,1392.0,0.,1392.);
    141     //IUFillNumber(&GuiderN[1],"HEIGHT","Height","%4.0f",0.,1040.,0.,1040.);
    142     //IUFillNumber(&GuiderN[2],"MAXGOODDATA","max good","%5.0f",0.,65535.0,0.,65535.0);
    143     //IUFillNumber(&GuiderN[3],"BYTESPERPIXEL","BPP","%1.0f",1.,4.,1.,2.);
    144     //IUFillNumber(&GuiderN[4],"BYTEORDER","BO","%1.0f",1.,2.,1.,1.);
    145     //IUFillNumberVector(&GuiderNV,GuiderN,5,deviceName(),"CCDPREVIEW_CTRL","Image Size","Guider Settings",IP_RW,60,IPS_IDLE);
    146 
    147     return 0;
     176    // PRIMARY CCD Init
     177
     178    IUFillNumber(&PrimaryCCD.ImageFrameN[0],"X","Left ","%4.0f",0,1392.0,0,0);
     179    IUFillNumber(&PrimaryCCD.ImageFrameN[1],"Y","Top","%4.0f",0,1040,0,0);
     180    IUFillNumber(&PrimaryCCD.ImageFrameN[2],"WIDTH","Width","%4.0f",0,1392.0,0,1392.0);
     181    IUFillNumber(&PrimaryCCD.ImageFrameN[3],"HEIGHT","Height","%4.0f",0,1040,0,1040);
     182    IUFillNumberVector(PrimaryCCD.ImageFrameNP,PrimaryCCD.ImageFrameN,4,deviceName(),"CCD_FRAME","Frame",IMAGE_SETTINGS_TAB,IP_RW,60,IPS_IDLE);
     183
     184    IUFillSwitch(&PrimaryCCD.FrameTypeS[0],"FRAME_LIGHT","Light",ISS_ON);
     185    IUFillSwitch(&PrimaryCCD.FrameTypeS[1],"FRAME_BIAS","Bias",ISS_OFF);
     186    IUFillSwitch(&PrimaryCCD.FrameTypeS[2],"FRAME_DARK","Dark",ISS_OFF);
     187    IUFillSwitch(&PrimaryCCD.FrameTypeS[3],"FRAME_FLAT","Flat",ISS_OFF);
     188    IUFillSwitchVector(PrimaryCCD.FrameTypeSP,PrimaryCCD.FrameTypeS,4,deviceName(),"CCD_FRAME_TYPE","FrameType",IMAGE_SETTINGS_TAB,IP_RW,ISR_1OFMANY,60,IPS_IDLE);
     189
     190    IUFillNumber(&PrimaryCCD.ImageExposureN[0],"CCD_EXPOSURE_VALUE","Duration (s)","%5.2f",0,36000,0,1.0);
     191    IUFillNumberVector(PrimaryCCD.ImageExposureNP,PrimaryCCD.ImageExposureN,1,deviceName(),"CCD_EXPOSURE_REQUEST","Expose",MAIN_CONTROL_TAB,IP_RW,60,IPS_IDLE);
     192
     193    IUFillNumber(&PrimaryCCD.ImageBinN[0],"HOR_BIN","X","%2.0f",1,4,1,1);
     194    IUFillNumber(&PrimaryCCD.ImageBinN[1],"VER_BIN","Y","%2.0f",1,4,1,1);
     195    IUFillNumberVector(PrimaryCCD.ImageBinNP,PrimaryCCD.ImageBinN,2,deviceName(),"CCD_BINNING","Binning",IMAGE_SETTINGS_TAB,IP_RW,60,IPS_IDLE);
     196
     197    IUFillNumber(&PrimaryCCD.ImagePixelSizeN[0],"CCD_MAX_X","Resolution x","%4.0f",1,40,0,6.45);
     198    IUFillNumber(&PrimaryCCD.ImagePixelSizeN[1],"CCD_MAX_Y","Resolution y","%4.0f",1,40,0,6.45);
     199    IUFillNumber(&PrimaryCCD.ImagePixelSizeN[2],"CCD_PIXEL_SIZE","Pixel size (um)","%5.2f",1,40,0,6.45);
     200    IUFillNumber(&PrimaryCCD.ImagePixelSizeN[3],"CCD_PIXEL_SIZE_X","Pixel size X","%5.2f",1,40,0,6.45);
     201    IUFillNumber(&PrimaryCCD.ImagePixelSizeN[4],"CCD_PIXEL_SIZE_Y","Pixel size Y","%5.2f",1,40,0,6.45);
     202    IUFillNumber(&PrimaryCCD.ImagePixelSizeN[5],"CCD_BITSPERPIXEL","Bits per pixel","%3.0f",1,40,0,6.45);
     203    IUFillNumberVector(PrimaryCCD.ImagePixelSizeNP,PrimaryCCD.ImagePixelSizeN,6,deviceName(),"CCD_INFO","Ccd Information",IMAGE_INFO_TAB,IP_RO,60,IPS_IDLE);
     204
     205    IUFillSwitch(&PrimaryCCD.CompressS[0],"COMPRESS","Compress",ISS_OFF);
     206    IUFillSwitch(&PrimaryCCD.CompressS[1],"RAW","Raw",ISS_ON);
     207    IUFillSwitchVector(PrimaryCCD.CompressSP,PrimaryCCD.CompressS,2,deviceName(),"COMPRESSION","Image",IMAGE_SETTINGS_TAB,IP_RW,ISR_1OFMANY,60,IPS_IDLE);
     208
     209    IUFillBLOB(&PrimaryCCD.FitsB,"CCD1","Image","");
     210    IUFillBLOBVector(PrimaryCCD.FitsBP,&PrimaryCCD.FitsB,1,deviceName(),"CCD1","Image Data",OPTIONS_TAB,IP_RO,60,IPS_IDLE);
     211
     212    // GUIDER CCD Init
     213
     214    IUFillNumber(&GuideCCD.ImageFrameN[0],"X","Left ","%4.0f",0,1392.0,0,0);
     215    IUFillNumber(&GuideCCD.ImageFrameN[1],"Y","Top","%4.0f",0,1040,0,0);
     216    IUFillNumber(&GuideCCD.ImageFrameN[2],"WIDTH","Width","%4.0f",0,1392.0,0,1392.0);
     217    IUFillNumber(&GuideCCD.ImageFrameN[3],"HEIGHT","Height","%4.0f",0,1040,0,1040);
     218    IUFillNumberVector(GuideCCD.ImageFrameNP,GuideCCD.ImageFrameN,4,deviceName(),"GUIDE_FRAME","Frame",GUIDE_HEAD_TAB,IP_RW,60,IPS_IDLE);
     219
     220    IUFillNumber(&GuideCCD.ImagePixelSizeN[0],"Image_MAX_X","Resolution x","%4.0f",1,40,0,6.45);
     221    IUFillNumber(&GuideCCD.ImagePixelSizeN[1],"Image_MAX_Y","Resolution y","%4.0f",1,40,0,6.45);
     222    IUFillNumber(&GuideCCD.ImagePixelSizeN[2],"Image_PIXEL_SIZE","Pixel size (um)","%5.2f",1,40,0,6.45);
     223    IUFillNumber(&GuideCCD.ImagePixelSizeN[3],"Image_PIXEL_SIZE_X","Pixel size X","%5.2f",1,40,0,6.45);
     224    IUFillNumber(&GuideCCD.ImagePixelSizeN[4],"Image_PIXEL_SIZE_Y","Pixel size Y","%5.2f",1,40,0,6.45);
     225    IUFillNumber(&GuideCCD.ImagePixelSizeN[5],"Image_BITSPERPIXEL","Bits per pixel","%3.0f",1,40,0,6.45);
     226    IUFillNumberVector(GuideCCD.ImagePixelSizeNP,GuideCCD.ImagePixelSizeN,6,deviceName(),"GUIDE_INFO",GUIDE_HEAD_TAB,GUIDE_HEAD_TAB,IP_RO,60,IPS_IDLE);
     227
     228    IUFillNumber(&GuideCCD.ImageExposureN[0],"GUIDER_EXPOSURE_VALUE","Duration (s)","%5.2f",0,36000,0,1.0);
     229    IUFillNumberVector(GuideCCD.ImageExposureNP,GuideCCD.ImageExposureN,1,deviceName(),"GUIDER_EXPOSURE","Image",MAIN_CONTROL_TAB,IP_RW,60,IPS_IDLE);
     230
     231    IUFillSwitch(&GuideCCD.CompressS[0],"GCOMPRESS","Compress",ISS_OFF);
     232    IUFillSwitch(&GuideCCD.CompressS[1],"GRAW","Raw",ISS_ON);
     233    IUFillSwitchVector(GuideCCD.CompressSP,GuideCCD.CompressS,2,deviceName(),"GCOMPRESSION","Image",GUIDE_HEAD_TAB,IP_RW,ISR_1OFMANY,60,IPS_IDLE);
     234
     235    IUFillBLOB(&GuideCCD.FitsB,"CCD2","Guider Image","");
     236    IUFillBLOBVector(GuideCCD.FitsBP,&GuideCCD.FitsB,1,deviceName(),"CCD2","Image Data",OPTIONS_TAB,IP_RO,60,IPS_IDLE);
     237
     238    // CCD Class Init
     239
     240    IUFillText(&TelescopeT[0],"ACTIVE_TELESCOPE","Telescope","");
     241    IUFillTextVector(TelescopeTP,TelescopeT,1,deviceName(),"ACTIVE_DEVICES","Snoop Scope",OPTIONS_TAB,IP_RW,60,IPS_IDLE);
     242
     243    IUFillNumber(&EqN[0],"RA_PEC","Ra (hh:mm:ss)","%010.6m",0,24,0,0);
     244    IUFillNumber(&EqN[1],"DEC_PEC","Dec (dd:mm:ss)","%010.6m",-90,90,0,0);
     245    IUFillNumberVector(&EqNP,EqN,2,"","EQUATORIAL_PEC","EQ PEC","Main Control",IP_RW,60,IPS_IDLE);
     246
     247    // Guider Interface
     248    initGuiderProperties(deviceName(), GUIDE_CONTROL_TAB);
     249
     250    return true;
    148251}
    149252
     
    162265{
    163266    //IDLog("INDI::CCD UpdateProperties isConnected returns %d %d\n",isConnected(),Connected);
    164     if(isConnected()) {
    165         defineNumber(&ImageExposureNV);
    166         defineNumber(&ImageFrameNV);
    167         defineNumber(&ImageBinNV);
    168 
    169 
    170         if(HasGuideHead) {
     267    if(isConnected())
     268    {
     269        defineNumber(PrimaryCCD.ImageExposureNP);
     270        defineNumber(PrimaryCCD.ImageFrameNP);
     271        defineNumber(PrimaryCCD.ImageBinNP);
     272
     273        if(HasGuideHead)
     274        {
    171275            IDLog("Sending Guider Stuff\n");
    172             defineNumber(&GuiderExposureNV);
    173             defineNumber(&GuiderFrameNV);
    174             defineSwitch(&GuiderVideoSV);
    175         }
    176 
    177         defineNumber(&ImagePixelSizeNV);
    178         if(HasGuideHead) {
    179             defineNumber(&GuiderPixelSizeNV);
    180         }
    181         defineSwitch(&CompressSV);
    182         defineBLOB(&FitsBV);
     276            defineNumber(GuideCCD.ImageExposureNP);
     277            defineNumber(GuideCCD.ImageFrameNP);
     278        }
     279
     280        defineNumber(PrimaryCCD.ImagePixelSizeNP);
    183281        if(HasGuideHead)
    184282        {
    185             defineSwitch(&GuiderCompressSV);
    186             defineBLOB(&GuiderBV);
     283            defineNumber(GuideCCD.ImagePixelSizeNP);
     284        }
     285        defineSwitch(PrimaryCCD.CompressSP);
     286        defineBLOB(PrimaryCCD.FitsBP);
     287        if(HasGuideHead)
     288        {
     289            defineSwitch(GuideCCD.CompressSP);
     290            defineBLOB(GuideCCD.FitsBP);
    187291        }
    188292        if(HasSt4Port)
    189293        {
    190             defineNumber(&GuideNSV);
    191             defineNumber(&GuideEWV);
    192         }
    193         defineSwitch(&FrameTypeSV);
    194     } else {
    195         deleteProperty(ImageFrameNV.name);
    196         deleteProperty(ImageBinNV.name);
    197         deleteProperty(ImagePixelSizeNV.name);
    198         deleteProperty(ImageExposureNV.name);
    199         deleteProperty(FitsBV.name);
    200         deleteProperty(CompressSV.name);
    201         if(HasGuideHead) {
    202             deleteProperty(GuiderVideoSV.name);
    203             deleteProperty(GuiderExposureNV.name);
    204             deleteProperty(GuiderFrameNV.name);
    205             deleteProperty(GuiderPixelSizeNV.name);
    206             deleteProperty(GuiderBV.name);
    207             deleteProperty(GuiderCompressSV.name);
    208         }
    209         if(HasSt4Port) {
    210             deleteProperty(GuideNSV.name);
    211             deleteProperty(GuideEWV.name);
    212 
    213         }
    214         deleteProperty(FrameTypeSV.name);
     294            defineNumber(GuideNSP);
     295            defineNumber(GuideEWP);
     296        }
     297        defineSwitch(PrimaryCCD.FrameTypeSP);
     298        defineText(TelescopeTP);
     299    }
     300    else
     301    {
     302        deleteProperty(PrimaryCCD.ImageFrameNP->name);
     303        deleteProperty(PrimaryCCD.ImageBinNP->name);
     304        deleteProperty(PrimaryCCD.ImagePixelSizeNP->name);
     305        deleteProperty(PrimaryCCD.ImageExposureNP->name);
     306        deleteProperty(PrimaryCCD.FitsBP->name);
     307        deleteProperty(PrimaryCCD.CompressSP->name);
     308        if(HasGuideHead)
     309        {
     310            deleteProperty(GuideCCD.ImageExposureNP->name);
     311            deleteProperty(GuideCCD.ImageFrameNP->name);
     312            deleteProperty(GuideCCD.ImagePixelSizeNP->name);
     313            deleteProperty(GuideCCD.FitsBP->name);
     314            deleteProperty(GuideCCD.CompressSP->name);
     315        }
     316        if(HasSt4Port)
     317        {
     318            deleteProperty(GuideNSP->name);
     319            deleteProperty(GuideEWP->name);
     320
     321        }
     322        deleteProperty(PrimaryCCD.FrameTypeSP->name);
     323        deleteProperty(TelescopeTP->name);
    215324    }
    216325    return true;
    217326}
    218327
     328void INDI::CCD::ISSnoopDevice (XMLEle *root)
     329 {
     330     //fprintf(stderr," ################# CCDSim handling snoop ##############\n");
     331     if(IUSnoopNumber(root,&EqNP)==0)
     332     {
     333        float newra,newdec;
     334        newra=EqN[0].value;
     335        newdec=EqN[1].value;
     336        if((newra != RA)||(newdec != Dec))
     337        {
     338            //fprintf(stderr,"RA %4.2f  Dec %4.2f Snooped RA %4.2f  Dec %4.2f\n",RA,Dec,newra,newdec);
     339            RA=newra;
     340            Dec=newdec;
     341
     342        }
     343     }
     344     else
     345     {
     346        //fprintf(stderr,"Snoop Failed\n");
     347     }
     348 }
     349
     350bool INDI::CCD::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
     351{
     352    //  Ok, lets see if this is a property wer process
     353    //IDLog("IndiTelescope got %d new text items name %s\n",n,name);
     354    //  first check if it's for our device
     355    if(strcmp(dev,deviceName())==0)
     356    {
     357        //  This is for our device
     358        //  Now lets see if it's something we process here
     359        if(strcmp(name,TelescopeTP->name)==0)
     360        {
     361            int rc;
     362            //IDLog("calling update text\n");
     363            TelescopeTP->s=IPS_OK;
     364            rc=IUUpdateText(TelescopeTP,texts,names,n);
     365            //IDLog("update text returns %d\n",rc);
     366            //  Update client display
     367            IDSetText(TelescopeTP,NULL);
     368            saveConfig();
     369            IUFillNumberVector(&EqNP,EqN,2,TelescopeT[0].text,"EQUATORIAL_PEC","EQ PEC",MAIN_CONTROL_TAB,IP_RW,60,IPS_IDLE);
     370            IDSnoopDevice(TelescopeT[0].text,"EQUATORIAL_PEC");
     371            //  We processed this one, so, tell the world we did it
     372            return true;
     373        }
     374
     375    }
     376
     377    return INDI::DefaultDriver::ISNewText(dev,name,texts,names,n);
     378}
     379
    219380bool INDI::CCD::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
    220381{
    221382    //  first check if it's for our device
    222383    //IDLog("INDI::CCD::ISNewNumber %s\n",name);
    223     if(strcmp(dev,deviceName())==0) {
     384    if(strcmp(dev,deviceName())==0)
     385    {
    224386        //  This is for our device
    225387        //  Now lets see if it's something we process here
    226         if(strcmp(name,"CCD_EXPOSURE")==0) {
     388        if(strcmp(name,"CCD_EXPOSURE_REQUEST")==0)
     389        {
    227390            float n;
    228391            int rc;
     
    230393            n=values[0];
    231394
    232             ImageExposureN[0].value=n;
    233             ImageExposureNV.s=IPS_BUSY;
     395            PrimaryCCD.ImageExposureN[0].value=n;
     396
     397            if (PrimaryCCD.ImageExposureNP->s==IPS_BUSY)
     398                AbortExposure();
     399
     400            PrimaryCCD.ImageExposureNP->s=IPS_BUSY;
    234401            //  now we have a new number, this is our requested exposure time
    235402            //  Tell the clients we are busy with this exposure
     
    237404            //  And now call the physical hardware layer to start the exposure
    238405            rc=StartExposure(n);
    239             switch(rc) {
     406            switch(rc)
     407            {
    240408                case 0: //  normal case, exposure running on timers, callbacks when it's finished
    241                     ImageExposureNV.s=IPS_BUSY;
     409                    PrimaryCCD.ImageExposureNP->s=IPS_BUSY;
    242410                    break;
    243411                case 1: //  Short exposure, it's already done
    244                     ImageExposureNV.s=IPS_OK;
     412                    PrimaryCCD.ImageExposureNP->s=IPS_OK;
    245413                    break;
    246414                case -1:    //  error condition
    247                     ImageExposureNV.s=IPS_ALERT;
     415                    PrimaryCCD.ImageExposureNP->s=IPS_ALERT;
    248416                break;
    249417            }
    250             IDSetNumber(&ImageExposureNV,NULL);
    251             return true;
    252         }
    253 
    254         if(strcmp(name,"GUIDER_EXPOSURE")==0) {
     418            IDSetNumber(PrimaryCCD.ImageExposureNP,NULL);
     419            return true;
     420        }
     421
     422        if(strcmp(name,"GUIDER_EXPOSURE")==0)
     423        {
    255424            float n;
    256425            int rc;
     
    258427            n=values[0];
    259428
    260             GuiderExposureN[0].value=n;
    261             GuiderExposureNV.s=IPS_BUSY;
     429            GuideCCD.ImageExposureN[0].value=n;
     430            GuideCCD.ImageExposureNP->s=IPS_BUSY;
    262431            //  now we have a new number, this is our requested exposure time
    263432            //  Tell the clients we are busy with this exposure
     
    270439            switch(rc) {
    271440                case 0: //  normal case, exposure running on timers, callbacks when it's finished
    272                     GuiderExposureNV.s=IPS_BUSY;
     441                    GuideCCD.ImageExposureNP->s=IPS_BUSY;
    273442                    break;
    274443                case 1: //  Short exposure, it's already done
    275                     GuiderExposureNV.s=IPS_OK;
     444                    GuideCCD.ImageExposureNP->s=IPS_OK;
    276445                    break;
    277446                case -1:    //  error condition
    278                     GuiderExposureNV.s=IPS_ALERT;
     447                    GuideCCD.ImageExposureNP->s=IPS_ALERT;
    279448                break;
    280449            }
    281             IDSetNumber(&GuiderExposureNV,NULL);
    282             return true;
    283         }
    284         if(strcmp(name,"CCD_BINNING")==0) {
     450            IDSetNumber(GuideCCD.ImageExposureNP,NULL);
     451            return true;
     452        }
     453
     454        if(strcmp(name,"CCD_BINNING")==0)
     455        {
    285456            //  We are being asked to set camera binning
    286             ImageBinNV.s=IPS_OK;
    287             IUUpdateNumber(&ImageBinNV,values,names,n);
     457            PrimaryCCD.ImageBinNP->s=IPS_OK;
     458            IUUpdateNumber(PrimaryCCD.ImageBinNP,values,names,n);
     459
     460            // Let child classes know of CCD BIN changes
     461            // If child processes and updates bin (true) then no further action is needed
     462            // if child class does not do any processing, then we simply update the values.
     463            if (updateCCDBin(PrimaryCCD.ImageBinN[0].value, PrimaryCCD.ImageBinN[1].value) == false)
     464                PrimaryCCD.setBin(PrimaryCCD.ImageBinN[0].value, PrimaryCCD.ImageBinN[1].value);
     465
     466            return true;
     467
     468        }
     469
     470        if(strcmp(name,"CCD_FRAME")==0)
     471        {
     472            //  We are being asked to set camera binning
     473            PrimaryCCD.ImageFrameNP->s=IPS_OK;
     474            IUUpdateNumber(PrimaryCCD.ImageFrameNP,values,names,n);
    288475            //  Update client display
    289             IDSetNumber(&ImageBinNV,NULL);
    290 
    291             //IDLog("Binning set to %4.0f x %4.0f\n",CcdBinN[0].value,CcdBinN[1].value);
    292             BinX=ImageBinN[0].value;
    293             BinY=ImageBinN[1].value;
    294         }
    295         if(strcmp(name,"CCD_FRAME")==0) {
     476            //IDSetNumber(PrimaryCCD.ImageFrameNP,NULL);
     477
     478            //IDLog("Frame set to %4.0f,%4.0f %4.0f x %4.0f\n",CcdFrameN[0].value,CcdFrameN[1].value,CcdFrameN[2].value,CcdFrameN[3].value);
     479            //SubX=PrimaryCCD.ImageFrameN[0].value;
     480            //SubY=PrimaryCCD.ImageFrameN[1].value;
     481            //SubW=PrimaryCCD.ImageFrameN[2].value;
     482            //SubH=PrimaryCCD.ImageFrameN[3].value;
     483
     484            if (updateCCDFrame(PrimaryCCD.ImageFrameN[0].value, PrimaryCCD.ImageFrameN[1].value, PrimaryCCD.ImageFrameN[2].value,
     485                               PrimaryCCD.ImageFrameN[3].value) == false)
     486                PrimaryCCD.setFrame(PrimaryCCD.ImageFrameN[0].value, PrimaryCCD.ImageFrameN[1].value, PrimaryCCD.ImageFrameN[2].value,
     487                                    PrimaryCCD.ImageFrameN[3].value);
     488            return true;
     489        }
     490
     491        if(strcmp(name,"GUIDER_FRAME")==0)
     492        {
    296493            //  We are being asked to set camera binning
    297             ImageFrameNV.s=IPS_OK;
    298             IUUpdateNumber(&ImageFrameNV,values,names,n);
     494            GuideCCD.ImageFrameNP->s=IPS_OK;
     495            IUUpdateNumber(GuideCCD.ImageFrameNP,values,names,n);
    299496            //  Update client display
    300             IDSetNumber(&ImageFrameNV,NULL);
    301 
    302             //IDLog("Frame set to %4.0f,%4.0f %4.0f x %4.0f\n",CcdFrameN[0].value,CcdFrameN[1].value,CcdFrameN[2].value,CcdFrameN[3].value);
    303             SubX=ImageFrameN[0].value;
    304             SubY=ImageFrameN[1].value;
    305             SubW=ImageFrameN[2].value;
    306             SubH=ImageFrameN[3].value;
    307             return true;
    308         }
    309 
    310         if(strcmp(name,"GUIDER_FRAME")==0) {
    311             //  We are being asked to set camera binning
    312             GuiderFrameNV.s=IPS_OK;
    313             IUUpdateNumber(&GuiderFrameNV,values,names,n);
     497            //IDSetNumber(GuiderFrameNP,NULL);
     498
     499            IDLog("GuiderFrame set to %4.0f,%4.0f %4.0f x %4.0f\n",
     500                  GuideCCD.ImageFrameN[0].value,GuideCCD.ImageFrameN[1].value,GuideCCD.ImageFrameN[2].value,GuideCCD.ImageFrameN[3].value);
     501            //GSubX=GuiderFrameN[0].value;
     502            //GSubY=GuiderFrameN[1].value;
     503            //GSubW=GuiderFrameN[2].value;
     504            //GSubH=GuiderFrameN[3].value;
     505            GuideCCD.setFrame(GuideCCD.ImageFrameN[0].value, GuideCCD.ImageFrameN[1].value,
     506                              GuideCCD.ImageFrameN[2].value,GuideCCD.ImageFrameN[3].value);
     507
     508            return true;
     509        }
     510
     511        if(strcmp(name,GuideNSP->name)==0)
     512        {
     513            //  We are being asked to send a guide pulse north/south on the st4 port
     514            GuideNSP->s=IPS_BUSY;
     515            IUUpdateNumber(GuideNSP,values,names,n);
    314516            //  Update client display
    315             IDSetNumber(&GuiderFrameNV,NULL);
    316 
    317             IDLog("GuiderFrame set to %4.0f,%4.0f %4.0f x %4.0f\n",
    318                   GuiderFrameN[0].value,GuiderFrameN[1].value,GuiderFrameN[2].value,GuiderFrameN[3].value);
    319             GSubX=GuiderFrameN[0].value;
    320             GSubY=GuiderFrameN[1].value;
    321             GSubW=GuiderFrameN[2].value;
    322             GSubH=GuiderFrameN[3].value;
    323             return true;
    324         }
    325 
    326         if(strcmp(name,GuideNSV.name)==0) {
    327             //  We are being asked to send a guide pulse north/south on the st4 port
    328             GuideNSV.s=IPS_BUSY;
    329             IUUpdateNumber(&GuideNSV,values,names,n);
    330             //  Update client display
    331             IDSetNumber(&GuideNSV,NULL);
    332 
    333             fprintf(stderr,"GuideNorthSouth set to %7.3f,%7.3f\n",
    334                   GuideNS[0].value,GuideNS[1].value);
    335 
    336             if(GuideNS[0].value != 0) {
     517            IDSetNumber(GuideNSP,NULL);
     518
     519            fprintf(stderr,"GuideNorthSouth set to %7.3f,%7.3f\n", GuideNS[0].value,GuideNS[1].value);
     520
     521            if(GuideNS[0].value != 0)
     522            {
    337523                GuideNorth(GuideNS[0].value);
    338524            }
     
    342528            GuideNS[0].value=0;
    343529            GuideNS[1].value=0;
    344             GuideNSV.s=IPS_OK;
    345             IDSetNumber(&GuideNSV,NULL);
    346 
    347             return true;
    348         }
    349         if(strcmp(name,GuideEWV.name)==0) {
     530            GuideNSP->s=IPS_OK;
     531            IDSetNumber(GuideNSP,NULL);
     532
     533            return true;
     534        }
     535
     536        if(strcmp(name,GuideEWP->name)==0)
     537        {
    350538            //  We are being asked to send a guide pulse north/south on the st4 port
    351             GuideEWV.s=IPS_BUSY;
    352             IUUpdateNumber(&GuideEWV,values,names,n);
     539            GuideEWP->s=IPS_BUSY;
     540            IUUpdateNumber(GuideEWP,values,names,n);
    353541            //  Update client display
    354             IDSetNumber(&GuideEWV,NULL);
     542            IDSetNumber(GuideEWP,NULL);
    355543
    356544            fprintf(stderr,"GuiderEastWest set to %6.3f,%6.3f\n",
    357545                  GuideEW[0].value,GuideEW[1].value);
    358546
    359             if(GuideEW[0].value != 0) {
     547            if(GuideEW[0].value != 0)
     548            {
    360549                GuideEast(GuideEW[0].value);
    361             } else {
     550            } else
     551            {
    362552                GuideWest(GuideEW[1].value);
    363553            }
     
    365555            GuideEW[0].value=0;
    366556            GuideEW[1].value=0;
    367             GuideEWV.s=IPS_OK;
    368             IDSetNumber(&GuideEWV,NULL);
    369 
    370             return true;
    371         }
    372 
    373         /*
    374         if(strcmp(name,"CCDPREVIEW_CTRL")==0) {
    375             //  We are being asked to set camera binning
    376             GuiderNV.s=IPS_OK;
    377             IUUpdateNumber(&GuiderNV,values,names,n);
    378             //  Update client display
    379             IDSetNumber(&GuiderNV,NULL);
    380             return true;
    381         }
    382         */
     557            GuideEWP->s=IPS_OK;
     558            IDSetNumber(GuideEWP,NULL);
     559
     560            return true;
     561        }
    383562
    384563    }
     
    391570{
    392571
    393     //  Ok, lets Process any switches we actually handle here
    394     //IDLog("INDI::CCD IsNewSwitch %s %s\n",dev,name);
    395 
    396 
    397     if(strcmp(dev,deviceName())==0) {
    398         //  it's for this device
    399 
    400         //for(int x=0; x<n; x++) {
    401         //    IDLog("Switch %s\n",names[x]);
    402         //}
    403 
    404         if(strcmp(name,CompressSV.name)==0) {
    405 
    406             IUUpdateSwitch(&CompressSV,states,names,n);
    407             IDSetSwitch(&CompressSV,NULL);
    408 
    409             if(CompressS[0].s==ISS_ON    ) {
    410                 SendCompressed=true;
    411             } else {
    412                 SendCompressed=false;
     572    if(strcmp(dev,deviceName())==0)
     573    {
     574
     575
     576        if(strcmp(name,PrimaryCCD.CompressSP->name)==0)
     577        {
     578
     579            IUUpdateSwitch(PrimaryCCD.CompressSP,states,names,n);
     580            IDSetSwitch(PrimaryCCD.CompressSP,NULL);
     581
     582            if(PrimaryCCD.CompressS[0].s==ISS_ON    )
     583            {
     584                PrimaryCCD.SendCompressed=true;
     585            } else
     586            {
     587                PrimaryCCD.SendCompressed=false;
    413588            }
    414589            return true;
    415590        }
    416         if(strcmp(name,GuiderCompressSV.name)==0) {
    417 
    418             IUUpdateSwitch(&GuiderCompressSV,states,names,n);
    419             IDSetSwitch(&GuiderCompressSV,NULL);
    420 
    421             if(GuiderCompressS[0].s==ISS_ON    ) {
    422                 SendCompressed=true;
    423             } else {
    424                 SendCompressed=false;
     591
     592        if(strcmp(name,GuideCCD.CompressSP->name)==0)
     593        {
     594
     595            IUUpdateSwitch(GuideCCD.CompressSP,states,names,n);
     596            IDSetSwitch(GuideCCD.CompressSP,NULL);
     597
     598            if(GuideCCD.CompressS[0].s==ISS_ON    )
     599            {
     600                GuideCCD.SendCompressed=true;
     601            } else
     602            {
     603                GuideCCD.SendCompressed=false;
    425604            }
    426605            return true;
    427606        }
    428607
    429         if(strcmp(name,GuiderVideoSV.name)==0) {
     608        if(strcmp(name,PrimaryCCD.FrameTypeSP->name)==0)
     609        {
    430610            //  Compression Update
    431             IUUpdateSwitch(&GuiderVideoSV,states,names,n);
    432             if(GuiderVideoS[0].s==ISS_ON    ) {
    433                 GuiderVideoSV.s=IPS_OK;
    434                 StartGuideExposure(GuiderExposureN[0].value);
    435             } else {
    436                 AbortGuideExposure();
    437                 GuiderVideoSV.s=IPS_IDLE;
    438             }
    439 
    440             IDSetSwitch(&GuiderVideoSV,NULL);
    441             return true;
    442         }
    443 
    444         if(strcmp(name,FrameTypeSV.name)==0) {
    445             //  Compression Update
    446             IUUpdateSwitch(&FrameTypeSV,states,names,n);
    447             FrameTypeSV.s=IPS_OK;
    448             if(FrameTypeS[0].s==ISS_ON) SetFrameType(FRAME_TYPE_LIGHT);
    449             if(FrameTypeS[1].s==ISS_ON) SetFrameType(FRAME_TYPE_BIAS);
    450             if(FrameTypeS[2].s==ISS_ON) SetFrameType(FRAME_TYPE_DARK);
    451             if(FrameTypeS[3].s==ISS_ON) SetFrameType(FRAME_TYPE_FLAT);
    452 
    453 
    454             IDSetSwitch(&FrameTypeSV,NULL);
    455             return true;
    456         }
    457 
     611            IUUpdateSwitch(PrimaryCCD.FrameTypeSP,states,names,n);
     612            PrimaryCCD.FrameTypeSP->s=IPS_OK;
     613            if(PrimaryCCD.FrameTypeS[0].s==ISS_ON) PrimaryCCD.setFrameType(CCDChip::LIGHT_FRAME);
     614            if(PrimaryCCD.FrameTypeS[1].s==ISS_ON) PrimaryCCD.setFrameType(CCDChip::BIAS_FRAME);
     615            if(PrimaryCCD.FrameTypeS[2].s==ISS_ON) PrimaryCCD.setFrameType(CCDChip::DARK_FRAME);
     616            if(PrimaryCCD.FrameTypeS[3].s==ISS_ON) PrimaryCCD.setFrameType(CCDChip::FLAT_FRAME);
     617
     618            IDSetSwitch(PrimaryCCD.FrameTypeSP,NULL);
     619            return true;
     620        }
    458621    }
    459622
     
    475638    return -1;
    476639}
     640
     641bool INDI::CCD::AbortExposure()
     642{
     643    IDLog("INDI::CCD::AbortExposure -  Should never get here\n");
     644    return false;
     645}
     646
     647bool INDI::CCD::updateCCDFrame(int x, int y, int w, int h)
     648{
     649    // Nothing to do here. HW layer should take care of it if needed.
     650    return false;
     651}
     652
     653bool INDI::CCD::updateCCDBin(int hor, int ver)
     654{
     655    // Nothing to do here. HW layer should take care of it if needed.
     656    return false;
     657}
     658
     659void INDI::CCD::addFITSKeywords(fitsfile *fptr)
     660{
     661    // Nothing to do here. HW layer should take care of it if needed.
     662}
     663
    477664bool INDI::CCD::ExposureComplete()
    478665{
     
    482669    long naxes[2];
    483670    long naxis=2;
     671    int numbytes=0;
    484672
    485673    fitsfile *fptr=NULL;
    486674
    487 
    488675    //IDLog("Enter Exposure Complete %d %d %d %d\n",SubW,SubH,BinX,BinY);
    489676
    490 
    491     naxes[0]=SubW/BinX;
    492     naxes[1]=SubH/BinY;
     677    naxes[0]=PrimaryCCD.getSubW()/PrimaryCCD.getBinX();
     678    naxes[1]=PrimaryCCD.getSubH()/PrimaryCCD.getBinY();
     679
     680    numbytes = naxes[0] * naxes[1];
     681
    493682    //  Now we have to send fits format data to the client
    494683    memsize=5760;
    495684    memptr=malloc(memsize);
    496     if(!memptr) {
     685    if(!memptr)
     686    {
    497687        IDLog("Error: failed to allocate memory: %lu\n",(unsigned long)memsize);
    498688    }
     689
    499690    fits_create_memfile(&fptr,&memptr,&memsize,2880,realloc,&status);
    500     if(status) {
     691
     692    if(status)
     693    {
    501694                IDLog("Error: Failed to create FITS image\n");
    502695                fits_report_error(stderr, status);  /* print out any error messages */
    503696                return false;
    504697    }
    505         fits_create_img(fptr, USHORT_IMG , naxis, naxes, &status);
    506         if (status)
    507         {
     698
     699    fits_create_img(fptr, USHORT_IMG , naxis, naxes, &status);
     700
     701    if (status)
     702    {
    508703                IDLog("Error: Failed to create FITS image\n");
    509704                fits_report_error(stderr, status);  /* print out any error messages */
    510705                return false;
    511         }
    512 
    513     fits_write_img(fptr,TUSHORT,1,SubW*SubH/BinX/BinY,RawFrame,&status);
     706    }
     707
     708    addFITSKeywords(fptr);
     709
     710    fits_write_img(fptr,TUSHORT,1,numbytes,PrimaryCCD.getFrameBuffer(),&status);
     711
    514712    if (status)
    515         {
     713    {
    516714                IDLog("Error: Failed to write FITS image\n");
    517715                fits_report_error(stderr, status);  /* print out any error messages */
    518716                return false;
    519         }
    520         fits_close_file(fptr,&status);
    521         //IDLog("Built the fits file\n");
    522 
    523     //  ok, undo the kludge we threw in for
    524     //  guider frames, and set the resolution back
    525 
    526     //ImageFrameN[2].value=SubW;
    527     //ImageFrameN[3].value=SubH;
    528     //IDSetNumber(&ImageFrameNV,NULL);
    529 
    530 
    531     ImageExposureNV.s=IPS_OK;
    532     IDSetNumber(&ImageExposureNV,NULL);
     717    }
     718
     719    fits_close_file(fptr,&status);
     720
     721
     722    PrimaryCCD.ImageExposureNP->s=IPS_OK;
     723    IDSetNumber(PrimaryCCD.ImageExposureNP,NULL);
    533724
    534725    uploadfile(memptr,memsize);
     
    539730bool INDI::CCD::GuideExposureComplete()
    540731{
    541 
    542     //IDLog("Enter GuideExposure Complete %d %d\n",GSubW,GSubH);
    543 
    544     if(GuiderVideoS[0].s==ISS_ON) {
    545         //  if our stream switch for the guider
    546         //  is on, then send this as a video stream
    547         //  frame, and, start another frame
    548 
    549         //  Ok, bit of a kludge here
    550         //  we need to send a new size to kstars
    551         //ImageFrameN[2].value=GSubW;
    552         //ImageFrameN[3].value=GSubH;
    553         //IDSetNumber(&ImageFrameNV,NULL);
    554 
    555         //IDLog("Sending guider stream blob\n");
    556 
    557         GuiderExposureNV.s=IPS_OK;
    558         IDSetNumber(&GuiderExposureNV,NULL);
    559         GuiderB.blob=RawGuiderFrame;
    560         GuiderB.bloblen=GSubW*GSubH;
    561         GuiderB.size=GSubW*GSubH;
    562         strcpy(GuiderB.format,".stream");
    563         GuiderBV.s=IPS_OK;
    564         IDSetBLOB(&GuiderBV,NULL);
    565         StartGuideExposure(GuiderExposureN[0].value);
    566     } else {
    567         //  We are not streaming
    568         //  So, lets send this as an 8 bit fits frame
    569732        void *memptr;
    570733        size_t memsize;
     
    574737
    575738        fitsfile *fptr=NULL;
    576         naxes[0]=GSubW;
    577         naxes[1]=GSubH;
     739        naxes[0]=GuideCCD.getSubW();
     740        naxes[1]=GuideCCD.getSubH();
    578741        //  Now we have to send fits format data to the client
    579742        memsize=5760;
    580743        memptr=malloc(memsize);
    581         if(!memptr) {
     744        if(!memptr)
     745        {
    582746            IDLog("Error: failed to allocate memory: %lu\n",(unsigned long)memsize);
    583747        }
    584748        fits_create_memfile(&fptr,&memptr,&memsize,2880,realloc,&status);
    585         if(status) {
     749        if(status)
     750        {
    586751            IDLog("Error: Failed to create FITS image\n");
    587752            fits_report_error(stderr, status);  /* print out any error messages */
     
    596761        }
    597762
    598         fits_write_img(fptr,TBYTE,1,GSubW*GSubH,RawGuiderFrame,&status);
     763        fits_write_img(fptr,TBYTE,1,naxes[0]*naxes[1],GuideCCD.getFrameBuffer(),&status);
    599764        if (status)
    600765        {
     
    605770        fits_close_file(fptr,&status);
    606771        IDLog("Built the Guider fits file\n");
    607         GuiderExposureNV.s=IPS_OK;
    608         IDSetNumber(&GuiderExposureNV,NULL);
    609 
    610         IDLog("Sending guider fits file via %s\n",GuiderBV.name);
    611         GuiderB.blob=memptr;
    612         GuiderB.bloblen=memsize;
    613         GuiderB.size=memsize;
    614         strcpy(GuiderB.format,".fits");
    615         GuiderBV.s=IPS_OK;
    616         IDSetBLOB(&GuiderBV,NULL);
     772        GuideCCD.ImageExposureNP->s=IPS_OK;
     773        IDSetNumber(GuideCCD.ImageExposureNP,NULL);
     774
     775        IDLog("Sending guider fits file via %s\n",GuideCCD.FitsBP->name);
     776        GuideCCD.FitsB.blob=memptr;
     777        GuideCCD.FitsB.bloblen=memsize;
     778        GuideCCD.FitsB.size=memsize;
     779        strcpy(GuideCCD.FitsB.format,".fits");
     780        GuideCCD.FitsBP->s=IPS_OK;
     781        IDSetBLOB(GuideCCD.FitsBP,NULL);
    617782        free(memptr);
    618     }
    619 
    620783
    621784    return true;
     
    623786
    624787
    625 int INDI::CCD::sendPreview()
    626 {
    627     int numbytes;
    628     int xw;
    629     int yw;
    630     //unsigned char *compressed;
    631     //uLongf compressedbytes=0;
    632     //int ccount;
    633     //int r;
     788int INDI::CCD::uploadfile(void *fitsdata,int total)
     789{
     790    //  lets try sending a ccd preview
     791    //IDLog("Enter Uploadfile with %d total sending via %s\n",total,FitsBP->name);
     792    PrimaryCCD.FitsB.blob=fitsdata;
     793    PrimaryCCD.FitsB.bloblen=total;
     794    PrimaryCCD.FitsB.size=total;
     795    strcpy(PrimaryCCD.FitsB.format,".fits");
     796    PrimaryCCD.FitsBP->s=IPS_OK;
     797    IDSetBLOB(PrimaryCCD.FitsBP,NULL);
    634798
    635799    return 0;
    636     xw=SubW/BinX;
    637     yw=SubH/BinY;
    638 
    639     //GuiderNV.s=IPS_OK;
    640     //GuiderN[0].value=xw;
    641     //GuiderN[1].value=yw;
    642     //IDLog("Guider Frame %d x %d\n",xw,yw);
    643     //IDSetNumber(&GuiderNV,"Starting to send new preview frame\n");
    644 
    645     numbytes=xw*yw;
    646     numbytes=numbytes*2;
    647     //compressedbytes=numbytes+numbytes/64+16+3;
    648     //compressed=(unsigned char *)malloc(numbytes+numbytes/64+16+3);
    649     //r=compress2(compressed,&compressedbytes,(unsigned char *)RawFrame,numbytes,9);
    650     //if(r != Z_OK) {
    651     //    IDLog("Got an error from compress\n");
    652     //    return -1;
    653     //}
    654 
    655 
    656     //FitsB.blob=compressed;
    657     //FitsB.bloblen=compressedbytes;
    658     FitsB.blob=RawFrame;
    659     FitsB.bloblen=numbytes;
    660     FitsB.size=numbytes;
    661     FitsBV.s=IPS_OK;
    662     strcpy(FitsB.format,".ccdpreview");
    663     IDSetBLOB(&FitsBV,NULL);
    664     //IDLog("Done with SetBlob with %d compressed to %d\n",numbytes,compressedbytes);
    665     //free(compressed);
    666     return 0;
    667 
    668 }
    669 
    670 int INDI::CCD::uploadfile(void *fitsdata,int total)
    671 {
    672     //  lets try sending a ccd preview
    673 
    674 
    675     //IDLog("Enter Uploadfile with %d total sending via %s\n",total,FitsBV.name);
    676     FitsB.blob=fitsdata;
    677     FitsB.bloblen=total;
    678     FitsB.size=total;
    679     strcpy(FitsB.format,".fits");
    680     FitsBV.s=IPS_OK;
    681     IDSetBLOB(&FitsBV,NULL);
    682     //IDLog("Done with SetBlob\n");
    683 
    684     return 0;
    685 }
    686 
    687 int INDI::CCD::SetCCDParams(int x,int y,int bpp,float xf,float yf)
    688 {
    689     XRes=x;
    690     YRes=y;
    691     SubX=0;
    692     SubY=0;
    693     SubW=XRes;
    694     SubH=YRes;
    695     BinX=1;
    696     BinY=1;
    697 
    698     PixelSizex=xf;
    699     PixelSizey=yf;
    700     ImageFrameN[2].value=x;
    701     ImageFrameN[3].value=y;
    702     ImagePixelSizeN[0].value=x;
    703     ImagePixelSizeN[1].value=y;
    704     ImagePixelSizeN[2].value=xf;
    705     ImagePixelSizeN[3].value=xf;
    706     ImagePixelSizeN[4].value=yf;
    707     ImagePixelSizeN[5].value=bpp;
    708     return 0;
    709 }
    710 
    711 int INDI::CCD::SetGuidHeadParams(int x,int y,int bpp,float xf,float yf)
     800}
     801
     802void INDI::CCD::SetCCDParams(int x,int y,int bpp,float xf,float yf)
     803{
     804    PrimaryCCD.setResolutoin(x, y);
     805    PrimaryCCD.setFrame(0, 0, x, y);
     806    PrimaryCCD.setBin(1,1);
     807    PrimaryCCD.setPixelSize(xf, yf);
     808    PrimaryCCD.setBPP(bpp/8);
     809
     810}
     811
     812void INDI::CCD::SetGuidHeadParams(int x,int y,int bpp,float xf,float yf)
    712813{
    713814    HasGuideHead=true;
    714     GXRes=x;
    715     GYRes=y;
    716     GSubX=0;
    717     GSubY=0;
    718     GSubW=GXRes;
    719     GSubH=GYRes;
    720     GuiderFrameN[2].value=x;
    721     GuiderFrameN[3].value=y;
    722     GuiderPixelSizeN[0].value=x;
    723     GuiderPixelSizeN[1].value=y;
    724     GuiderPixelSizeN[2].value=xf;
    725     GuiderPixelSizeN[3].value=xf;
    726     GuiderPixelSizeN[4].value=yf;
    727     GuiderPixelSizeN[5].value=bpp;
    728     return 0;
     815
     816    GuideCCD.setResolutoin(x, y);
     817    GuideCCD.setFrame(0, 0, x, y);
     818    GuideCCD.setBin(1,1);
     819    GuideCCD.setPixelSize(xf, yf);
     820    GuideCCD.setBPP(bpp/8);
     821
    729822}
    730823
     
    734827}
    735828
    736 int INDI::CCD::GuideNorth(float)
    737 {
    738     return -1;
    739 }
    740 int INDI::CCD::GuideSouth(float)
    741 {
    742     return -1;
    743 }
    744 int INDI::CCD::GuideEast(float)
    745 {
    746     return -1;
    747 }
    748 int INDI::CCD::GuideWest(float)
    749 {
    750     return -1;
    751 }
    752 int INDI::CCD::SetFrameType(int t)
    753 {
    754     //fprintf(stderr,"Set frame type to %d\n",t);
    755     FrameType=t;
    756     return 0;
    757 }
     829
     830bool INDI::CCD::GuideNorth(float ms)
     831{
     832    return false;
     833}
     834bool INDI::CCD::GuideSouth(float ms)
     835{
     836    return false;
     837}
     838bool INDI::CCD::GuideEast(float ms)
     839{
     840    return false;
     841}
     842bool INDI::CCD::GuideWest(float ms)
     843{
     844    return false;
     845}
     846
  • BAORadio/libindi/libindi/libs/indibase/indiccd.h

    r504 r642  
    11/*******************************************************************************
    2   Copyright(c) 2010 Gerry Rozema. All rights reserved.
    3 
    4   This program is free software; you can redistribute it and/or modify it
    5   under the terms of the GNU General Public License as published by the Free
    6   Software Foundation; either version 2 of the License, or (at your option)
    7   any later version.
    8 
    9   This program is distributed in the hope that it will be useful, but WITHOUT
    10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    12   more details.
    13 
    14   You should have received a copy of the GNU General Public License along with
    15   this program; if not, write to the Free Software Foundation, Inc., 59
    16   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    17 
    18   The full GNU General Public License is included in this distribution in the
    19   file called LICENSE.
     2  Copyright(c) 2010, 2011 Gerry Rozema, Jasem Mutlaq. All rights reserved.
     3
     4 This library is free software; you can redistribute it and/or
     5 modify it under the terms of the GNU Library General Public
     6 License version 2 as published by the Free Software Foundation.
     7
     8 This library is distributed in the hope that it will be useful,
     9 but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     11 Library General Public License for more details.
     12
     13 You should have received a copy of the GNU Library General Public License
     14 along with this library; see the file COPYING.LIB.  If not, write to
     15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     16 Boston, MA 02110-1301, USA.
    2017*******************************************************************************/
     18
    2119
    2220#ifndef INDI_CCD_H
    2321#define INDI_CCD_H
    2422
     23#include <fitsio.h>
     24
    2525#include "defaultdriver.h"
    26 
    27 #define FRAME_TYPE_LIGHT 0
    28 #define FRAME_TYPE_BIAS 1
    29 #define FRAME_TYPE_DARK 2
    30 #define FRAME_TYPE_FLAT 3
    31 
    32 class INDI::CCD : public INDI::DefaultDriver
     26#include "indiguiderinterface.h"
     27
     28extern const char *IMAGE_SETTINGS_TAB;
     29extern const char *IMAGE_INFO_TAB;
     30extern const char *GUIDE_HEAD_TAB;
     31extern const char *GUIDE_CONTROL_TAB;
     32
     33class CCDChip
    3334{
    34     protected:
    35 
    36         char *RawFrame;
    37         int RawFrameSize;
    38 
    39         //  Altho these numbers are indeed stored in the indi properties
    40         //  It makes for much cleaner code if we have 'plain old number' copies
    41         //  So, when we process messages, just update both
    42 
    43         int XRes;   //  native resolution of the ccd
    44         int YRes;   //  ditto
    45         int SubX;   //  left side of the subframe we are requesting
    46         int SubY;   //  top of the subframe requested
    47         int SubW;   //  width of the subframe
    48         int SubH;   //  height of the subframe
    49         int BinX;   //  Binning requested in the x direction
    50         int BinY;   //  Binning requested in the Y direction
    51         float PixelSizex;   //  pixel size in microns, x direction
    52         float PixelSizey;   //  pixel size in microns, y direction
    53         bool SendCompressed;
    54 
    55         bool HasSt4Port;
    56 
    57         //  If the camera has a second ccd, or integrated guide head
    58         //  we need information on that one too
    59         bool HasGuideHead;
    60         char *RawGuiderFrame;
    61         int RawGuideSize;
    62         int GXRes;  //  native resolution of the guide head
    63         int GYRes;  //  native resolution
    64         int GSubX;  //  left side of the guide image subframe
    65         int GSubY;  //  top of the guide image subframe
    66         int GSubW;  //  Width of the guide image
    67         int GSubH;  //  Height of the guide image
    68         float GPixelSizex;  //  phyiscal size of the guider pixels
    69         float GPixelSizey;
    70         bool GuiderCompressed;
    71 
    72         int FrameType;
    73 
    74 
    75     private:
    76     public:
     35
     36public:
     37    CCDChip();
     38    ~CCDChip();
     39
     40    typedef enum { LIGHT_FRAME=0, BIAS_FRAME, DARK_FRAME, FLAT_FRAME } CCD_FRAME;
     41
     42    int getXRes() { return XRes; }
     43    int getYRes() { return YRes; }
     44    int getSubX() { return SubX; }
     45    int getSubY() { return SubY; }
     46    int getSubW() { return SubW; }
     47    int getSubH() { return SubH; }
     48    int getBinX() { return BinX; }
     49    int getBinY() { return BinY; }
     50    int getPixelSizeX() { return PixelSizex; }
     51    int getPixelSizeY() { return PixelSizey; }
     52    int getBPP() { return BPP; }
     53    int getFrameBufferSize() { return RawFrameSize; }
     54    double getExposure() { return ImageExposureN[0].value; }
     55    char *getFrameBuffer() { return RawFrame; }
     56    bool isCompressed() { return SendCompressed; }
     57    bool isInterlaced() { return Interlaced; }
     58    CCD_FRAME getFrameType() { return FrameType; }
     59
     60    void setResolutoin(int x, int y);
     61    void setFrame(int subx, int suby, int subw, int subh);
     62    void setBin(int hor, int ver);
     63    void setPixelSize(int x, int y);
     64    void setCompressed (bool cmp);
     65    void setInterlaced(bool intr);
     66    void setFrameBufferSize(int nbuf);
     67    void setBPP(int bpp);
     68    int setFrameType(CCD_FRAME);
     69    void setExposure(double duration);
     70    void setExposureFailed();
     71
     72private:
     73
     74    int XRes;   //  native resolution of the ccd
     75    int YRes;   //  ditto
     76    int SubX;   //  left side of the subframe we are requesting
     77    int SubY;   //  top of the subframe requested
     78    int SubW;   //  width of the subframe
     79    int SubH;   //  height of the subframe
     80    int BinX;   //  Binning requested in the x direction
     81    int BinY;   //  Binning requested in the Y direction
     82    float PixelSizex;   //  pixel size in microns, x direction
     83    float PixelSizey;   //  pixel size in microns, y direction
     84    int BPP;            //  Bytes per Pixel
     85    bool Interlaced;
     86    char *RawFrame;
     87    int RawFrameSize;
     88    bool SendCompressed;
     89    CCD_FRAME FrameType;
     90
     91    INumberVectorProperty *ImageExposureNP;
     92    INumber ImageExposureN[1];
     93
     94    INumberVectorProperty *ImageFrameNP;
     95    INumber ImageFrameN[4];
     96
     97    INumberVectorProperty *ImageBinNP;
     98    INumber ImageBinN[2];
     99
     100    INumberVectorProperty *ImagePixelSizeNP;
     101    INumber ImagePixelSizeN[6];
     102
     103    ISwitch FrameTypeS[4];
     104    ISwitchVectorProperty *FrameTypeSP;
     105
     106    ISwitch CompressS[2];
     107    ISwitchVectorProperty *CompressSP;
     108
     109    IBLOB FitsB;
     110    IBLOBVectorProperty *FitsBP;
     111
     112    friend class INDI::CCD;
     113};
     114
     115/**
     116 * \class INDI::CCD
     117   \brief Class to provide general functionality of CCD cameras with a single CCD sensor, or a primary CCD sensor in addition to a secondary CCD guide head.
     118
     119   It also implements the interface to perform guiding. The class enable the ability to \e snoop on telescope equatorial coordinates and record them in the
     120   FITS file before upload. Developers need to subclass INDI::CCD to implement any driver for CCD cameras within INDI.
     121
     122\author Gerry Rozema, Jasem Mutlaq
     123*/
     124class INDI::CCD : public INDI::DefaultDriver, INDI::GuiderInterface
     125{
     126      public:
    77127        CCD();
    78128        virtual ~CCD();
    79129
    80         //  A ccd needs to desribe the frame
    81         //INumberVectorProperty CcdFrameNV;
    82         //INumberVectorProperty CcdExposureNV;
    83         //INumberVectorProperty CcdBinNV;
    84         //INumberVectorProperty CcdPixelSizeNV;
    85 
    86 
    87         INumberVectorProperty ImageFrameNV;
    88         INumber ImageFrameN[4];
    89 
    90         INumberVectorProperty ImageBinNV;
    91         INumber ImageBinN[2];
    92 
    93         INumberVectorProperty ImagePixelSizeNV;
    94         INumber ImagePixelSizeN[6];
    95 
    96         INumberVectorProperty ImageExposureNV;
    97         INumber ImageExposureN[1];
    98 
    99         //INumberVectorProperty ImageExposureReqNV;
    100         //INumber ImageExposureReqN[1];
    101 
    102         INumberVectorProperty GuiderFrameNV;
    103         INumber GuiderFrameN[4];
    104         INumberVectorProperty GuiderPixelSizeNV;
    105         INumber GuiderPixelSizeN[6];
    106         INumberVectorProperty GuiderExposureNV;
    107         INumber GuiderExposureN[1];
    108 
    109         ISwitch FrameTypeS[4];
    110         ISwitchVectorProperty FrameTypeSV;
    111 
    112 
    113         ISwitch CompressS[2];
    114         ISwitchVectorProperty CompressSV;
    115 
    116         ISwitch GuiderCompressS[2];
    117         ISwitchVectorProperty GuiderCompressSV;
    118 
    119 
    120         ISwitch GuiderVideoS[2];
    121         ISwitchVectorProperty GuiderVideoSV;
    122 
    123         INumber GuideNS[2];
    124         INumberVectorProperty GuideNSV;
    125         INumber GuideEW[2];
    126         INumberVectorProperty GuideEWV;
    127 
    128         IBLOB FitsB;
    129         IBLOBVectorProperty FitsBV;
    130 
    131         IBLOB GuiderB;
    132         IBLOBVectorProperty GuiderBV;
    133 
    134         virtual bool  initProperties();
     130        virtual bool initProperties();
    135131        virtual bool updateProperties();
    136132        virtual void ISGetProperties (const char *dev);
    137 
    138133        virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
    139134        virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n);
    140 
    141         virtual bool ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) {return false;}
    142 
    143 
     135        virtual bool ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n);
     136        virtual void ISSnoopDevice (XMLEle *root);
     137
     138     protected:
     139        /** \brief Start exposing primary CCD chip
     140            \param duration Duration in seconds
     141            \return 0 if OK and exposure will take some time to complete, 1 if exposure is short and complete already (e.g. bias), -1 on error.
     142            \note This function is not implemented in INDI::CCD, it must be implemented in the child class
     143        */
    144144        virtual int StartExposure(float duration);
     145
     146        /** \brief Uploads primary CCD exposed buffer as FITS to the client. Dervied classes should class this function when an exposure is complete.
     147             \note This function is not implemented in INDI::CCD, it must be implemented in the child class
     148        */
    145149        virtual bool ExposureComplete();
     150
     151        /** \brief Abort ongoing exposure
     152            \return true is abort is successful, false otherwise.
     153            \note This function is not implemented in INDI::CCD, it must be implemented in the child class
     154        */
     155        virtual bool AbortExposure();
     156
     157        /** \brief Start exposing guide CCD chip
     158            \param duration Duration in seconds
     159            \return 0 if OK and exposure will take some time to complete, 1 if exposure is short and complete already (e.g. bias), -1 on error.
     160            \note This function is not implemented in INDI::CCD, it must be implemented in the child class
     161        */
    146162        virtual int StartGuideExposure(float duration);
     163
     164        /** \brief Abort ongoing exposure
     165            \return true is abort is successful, false otherwise.
     166            \note This function is not implemented in INDI::CCD, it must be implemented in the child class
     167        */
    147168        virtual bool AbortGuideExposure();
     169
     170        /** \brief Uploads Guide head CCD exposed buffer as FITS to the client. Dervied classes should class this function when an exposure is complete.
     171            \note This function is not implemented in INDI::CCD, it must be implemented in the child class
     172        */
    148173        virtual bool GuideExposureComplete();
    149         virtual int uploadfile(void *fitsdata,int total);
    150         virtual int sendPreview();
    151 
    152         //  Handy functions for child classes
    153         virtual int SetCCDParams(int x,int y,int bpp,float xf,float yf);
    154         virtual int SetGuidHeadParams(int x,int y,int bpp,float xf,float yf);
    155 
    156         virtual int GuideNorth(float);
    157         virtual int GuideSouth(float);
    158         virtual int GuideEast(float);
    159         virtual int GuideWest(float);
    160 
    161         virtual int SetFrameType(int);
     174
     175        /** \brief INDI::CCD calls this function when CCD Frame dimension needs to be updated in the hardware. Derived classes should implement this function
     176            \param x Subframe X coordinate in pixels.
     177            \param y Subframe Y coordinate in pixels.
     178            \param w Subframe width in pixels.
     179            \param h Subframe height in pixels.
     180            \note (0,0) is defined as most left, top pixel in the subframe.
     181            \return true is CCD chip update is successful, false otherwise.
     182            \note This function is not implemented in INDI::CCD, it must be implemented in the child class
     183        */
     184        virtual bool updateCCDFrame(int x, int y, int w, int h);
     185
     186        /** \brief INDI::CCD calls this function when CCD Binning needs to be updated in the hardware. Derived classes should implement this function
     187            \param hor Horizontal binning.
     188            \param ver Vertical binning.
     189            \return true is CCD chip update is successful, false otherwise.
     190            \note This function is not implemented in INDI::CCD, it must be implemented in the child class
     191        */
     192        virtual bool updateCCDBin(int hor, int ver);
     193
     194
     195        /** \brief Setup CCD paramters for primary CCD. Child classes call this function to update CCD paramaters
     196            \param x Frame X coordinates in pixels.
     197            \param y Frame Y coordinates in pixels.
     198            \param bpp Bits Per Pixels.
     199            \param xf X pixel size in microns.
     200            \param yf Y pixel size in microns.
     201        */
     202        virtual void SetCCDParams(int x,int y,int bpp,float xf,float yf);
     203
     204        /** \brief Setup CCD paramters for guide head CCD. Child classes call this function to update CCD paramaters
     205            \param x Frame X coordinates in pixels.
     206            \param y Frame Y coordinates in pixels.
     207            \param bpp Bits Per Pixels.
     208            \param xf X pixel size in microns.
     209            \param yf Y pixel size in microns.
     210        */
     211        virtual void SetGuidHeadParams(int x,int y,int bpp,float xf,float yf);
     212
     213
     214        /** \brief Guide northward for ms milliseconds
     215            \param ms Duration in milliseconds.
     216            \note This function is not implemented in INDI::CCD, it must be implemented in the child class
     217            \return True if successful, false otherwise.
     218        */
     219        virtual bool GuideNorth(float ms);
     220
     221        /** \brief Guide southward for ms milliseconds
     222            \param ms Duration in milliseconds.
     223            \note This function is not implemented in INDI::CCD, it must be implemented in the child class
     224            \return 0 if successful, -1 otherwise.
     225        */
     226        virtual bool GuideSouth(float ms);
     227
     228        /** \brief Guide easward for ms milliseconds
     229            \param ms Duration in milliseconds.
     230            \note This function is not implemented in INDI::CCD, it must be implemented in the child class
     231            \return 0 if successful, -1 otherwise.
     232        */
     233        virtual bool GuideEast(float ms);
     234
     235        /** \brief Guide westward for ms milliseconds
     236            \param ms Duration in milliseconds.
     237            \note This function is not implemented in INDI::CCD, it must be implemented in the child class
     238            \return 0 if successful, -1 otherwise.
     239        */
     240        virtual bool GuideWest(float ms);
     241
     242        float RA;
     243        float Dec;
     244        bool HasGuideHead;
     245        bool HasSt4Port;
     246        bool InExposure;
     247
     248        CCDChip PrimaryCCD;
     249        CCDChip GuideCCD;
     250
     251 private:
     252    //  We are going to snoop these from a telescope
     253    INumberVectorProperty EqNP;
     254    INumber EqN[2];
     255
     256    ITextVectorProperty *TelescopeTP;
     257    IText TelescopeT[1];
     258
     259    void addFITSKeywords(fitsfile *fptr);
     260    int uploadfile(void *fitsdata,int total);
    162261
    163262};
  • BAORadio/libindi/libindi/libs/indibase/indidevice.cpp

    r504 r642  
    299299    //  We dont actually implement a device here
    300300    //  So we cannot connect to it
     301IDLog("IndiDevice Connect, we should never get here\n");
    301302    IDMessage(deviceName(),"IndiDevice:: has no device attached....");
    302303    return false;
  • BAORadio/libindi/libindi/libs/indibase/indifilterwheel.cpp

    r504 r642  
    11/*******************************************************************************
    2   Copyright(c) 2010 Gerry Rozema. All rights reserved.
     2  Copyright(c) 2010, 2011 Gerry Rozema. All rights reserved.
    33
    4   This program is free software; you can redistribute it and/or modify it
    5   under the terms of the GNU General Public License as published by the Free
    6   Software Foundation; either version 2 of the License, or (at your option)
    7   any later version.
     4 This library is free software; you can redistribute it and/or
     5 modify it under the terms of the GNU Library General Public
     6 License version 2 as published by the Free Software Foundation.
    87
    9   This program is distributed in the hope that it will be useful, but WITHOUT
    10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    12   more details.
     8 This library is distributed in the hope that it will be useful,
     9 but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     11 Library General Public License for more details.
    1312
    14   You should have received a copy of the GNU General Public License along with
    15   this program; if not, write to the Free Software Foundation, Inc., 59
    16   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    17 
    18   The full GNU General Public License is included in this distribution in the
    19   file called LICENSE.
     13 You should have received a copy of the GNU Library General Public License
     14 along with this library; see the file COPYING.LIB.  If not, write to
     15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     16 Boston, MA 02110-1301, USA.
    2017*******************************************************************************/
    2118
     
    2724{
    2825    //ctor
    29     MaxFilter=12;
     26    MaxFilter=-1;
    3027}
    3128
     
    3532}
    3633
     34
    3735bool INDI::FilterWheel::initProperties()
    3836{
    39     DefaultDriver::initProperties();   //  let the base class flesh in what it wants
     37    DefaultDriver::initProperties();
    4038
    41     IUFillNumber(&FilterSlotN[0],"FILTER_SLOT_VALUE","Filter","%3.0f",1.0,12.0,1.0,1.0);
    42     IUFillNumberVector(&FilterSlotNV,FilterSlotN,1,deviceName(),"FILTER_SLOT","Filter","Main Control",IP_RW,60,IPS_IDLE);
    43 
    44     IUFillText(&FilterNameT[0],"FILTER1","1","");
    45     IUFillText(&FilterNameT[1],"FILTER2","2","");
    46     IUFillText(&FilterNameT[2],"FILTER3","3","");
    47     IUFillText(&FilterNameT[3],"FILTER4","4","");
    48     IUFillText(&FilterNameT[4],"FILTER5","5","");
    49     IUFillText(&FilterNameT[5],"FILTER6","6","");
    50     IUFillText(&FilterNameT[6],"FILTER7","7","");
    51     IUFillText(&FilterNameT[7],"FILTER8","8","");
    52     IUFillText(&FilterNameT[8],"FILTER9","9","");
    53     IUFillText(&FilterNameT[9],"FILTER10","10","");
    54     IUFillText(&FilterNameT[10],"FILTER11","11","");
    55     IUFillText(&FilterNameT[11],"FILTER12","12","");
    56     IUFillTextVector(&FilterNameTV,FilterNameT,12,deviceName(),"FILTER_NAME","Filter","Filters",IP_RW,60,IPS_IDLE);
    57 
    58     return 0;
     39    initFilterProperties(deviceName(), FILTER_TAB);
    5940}
    6041
     
    6647    if(isConnected())
    6748    {
    68         defineNumber(&FilterSlotNV);
    69         defineText(&FilterNameTV);
     49        defineNumber(FilterSlotNP);
     50
     51        if (GetFilterNames(deviceName(), FILTER_TAB))
     52            defineText(FilterNameTP);
    7053    }
    7154    return;
     
    7962    if(isConnected())
    8063    {
    81         IUFillNumber(&FilterSlotN[0],"FILTER_SLOT_VALUE","Filter","%3.0f",MinFilter,MaxFilter,1.0,CurrentFilter);
    82         defineNumber(&FilterSlotNV);
    83         IUFillTextVector(&FilterNameTV,FilterNameT,MaxFilter,deviceName(),"FILTER_NAME","Filter","Filters",IP_RW,60,IPS_IDLE);
    84         defineText(&FilterNameTV);
    85         //LoadFilterNames();
     64        initFilterProperties(deviceName(), FILTER_TAB);
     65        defineNumber(FilterSlotNP);
     66        if (GetFilterNames(deviceName(), FILTER_TAB))
     67            defineText(FilterNameTP);
    8668    } else
    8769    {
    88         deleteProperty(FilterSlotNV.name);
    89         deleteProperty(FilterNameTV.name);
     70        deleteProperty(FilterSlotNP->name);
     71        deleteProperty(FilterNameTP->name);
    9072    }
    9173
    9274    return true;
     75}
     76
     77bool INDI::FilterWheel::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
     78{
     79    return DefaultDriver::ISNewSwitch(dev, name, states, names,n);
    9380}
    9481
     
    9784    //  first check if it's for our device
    9885    //IDLog("INDI::FilterWheel::ISNewNumber %s\n",name);
    99     if(strcmp(dev,deviceName())==0) {
     86    if(strcmp(dev,deviceName())==0)
     87    {
    10088        //  This is for our device
    10189        //  Now lets see if it's something we process here
    10290
    103         if(strcmp(name,"FILTER_SLOT")==0) {
    104 
     91        if(strcmp(name,"FILTER_SLOT")==0)
     92        {
    10593            int f;
    10694
    10795            f=-1;
    108             for(int x=0; x<n; x++) {
    109                 if(strcmp(names[x],"FILTER_SLOT_VALUE")==0) {
     96            for(int x=0; x<n; x++)
     97            {
     98                if(strcmp(names[x],"FILTER_SLOT_VALUE")==0)
     99                {
    110100                    //  This is the new filter number we are being asked
    111101                    //  to set as active
     
    114104            }
    115105
    116             if(f != -1) {
     106            if(f != -1)
     107            {
    117108                //IDLog("Filter wheel got a filter slot change\n");
    118109                //  tell the client we are busy changing the filter
    119                 FilterSlotNV.s=IPS_BUSY;
    120                 IDSetNumber(&FilterSlotNV,NULL);
     110                FilterSlotNP->s=IPS_BUSY;
     111                IDSetNumber(FilterSlotNP,NULL);
    121112                //  Tell the hardware to change
    122113                SelectFilter(f);
     
    136127    //IDLog("INDI::FilterWheel got %d new text items name %s\n",n,name);
    137128    //  first check if it's for our device
    138     if(strcmp(dev,deviceName())==0) {
     129    if(strcmp(dev,deviceName())==0)
     130    {
    139131        //  This is for our device
    140132        //  Now lets see if it's something we process here
    141         if(strcmp(name,FilterNameTV.name)==0) {
    142             //  This is our port, so, lets process it
    143 
    144             //  Some clients insist on sending a port
    145             //  and they may not be configured for the
    146             //  correct port
    147             //  If we are already connected
    148             //  and running, it makes absolutely no sense
    149             //  to accept a new port value
    150             //  so lets just lie to them and say
    151             //  we did this, but, dont actually change anything
    152             //if(Connected) return true;
    153 
     133        if(strcmp(name,FilterNameTP->name)==0)
     134        {
    154135            int rc;
    155136            //IDLog("calling update text\n");
    156             FilterNameTV.s=IPS_OK;
    157             rc=IUUpdateText(&FilterNameTV,texts,names,n);
    158             //IDLog("update text returns %d\n",rc);
    159             //  Update client display
    160             IDSetText(&FilterNameTV,NULL);
    161             //SaveConfig();
     137            FilterNameTP->s=IPS_OK;
     138            rc=IUUpdateText(FilterNameTP,texts,names,n);
    162139
     140            if (SetFilterNames() == true)
     141                IDSetText(FilterNameTP,NULL);
     142            else
     143            {
     144                FilterNameTP->s = IPS_ALERT;
     145                IDSetText(FilterNameTP, "Error updating names of filters.");
     146            }
    163147            //  We processed this one, so, tell the world we did it
    164148            return true;
     
    170154}
    171155
    172 int INDI::FilterWheel::SelectFilterDone(int f)
    173 {
    174     //  The hardware has finished changing
    175     //  filters
    176     FilterSlotN[0].value=f;
    177     FilterSlotNV.s=IPS_OK;
    178     // Tell the clients we are done, and
    179     //  filter is now useable
    180     IDSetNumber(&FilterSlotNV,NULL);
    181     return 0;
    182 }
    183 
    184 int INDI::FilterWheel::SelectFilter(int)
    185 {
    186     return -1;
    187 }
    188 
    189156int INDI::FilterWheel::QueryFilter()
    190157{
     
    193160
    194161
     162bool INDI::FilterWheel::SelectFilter(int)
     163{
     164    return false;
     165}
     166
     167bool INDI::FilterWheel::SetFilterNames()
     168{
     169    return true;
     170}
     171
     172void INDI::FilterWheel::ISSnoopDevice (XMLEle *root)
     173{
     174 return;
     175}
     176
     177
     178bool INDI::FilterWheel::GetFilterNames(const char *deviceName, const char* groupName)
     179{
     180    INDI_UNUSED(deviceName);
     181    INDI_UNUSED(groupName);
     182    return false;
     183}
     184
     185
  • BAORadio/libindi/libindi/libs/indibase/indifilterwheel.h

    r504 r642  
    11/*******************************************************************************
    2   Copyright(c) 2010 Gerry Rozema. All rights reserved.
     2  Copyright(c) 2010, 2011 Gerry Rozema. All rights reserved.
    33
    4   This program is free software; you can redistribute it and/or modify it
    5   under the terms of the GNU General Public License as published by the Free
    6   Software Foundation; either version 2 of the License, or (at your option)
    7   any later version.
     4 This library is free software; you can redistribute it and/or
     5 modify it under the terms of the GNU Library General Public
     6 License version 2 as published by the Free Software Foundation.
    87
    9   This program is distributed in the hope that it will be useful, but WITHOUT
    10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    12   more details.
     8 This library is distributed in the hope that it will be useful,
     9 but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     11 Library General Public License for more details.
    1312
    14   You should have received a copy of the GNU General Public License along with
    15   this program; if not, write to the Free Software Foundation, Inc., 59
    16   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     13 You should have received a copy of the GNU Library General Public License
     14 along with this library; see the file COPYING.LIB.  If not, write to
     15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     16 Boston, MA 02110-1301, USA.
     17*******************************************************************************/
    1718
    18   The full GNU General Public License is included in this distribution in the
    19   file called LICENSE.
    20 *******************************************************************************/
    2119#ifndef INDI_FILTERWHEEL_H
    2220#define INDI_FILTERWHEEL_H
    2321
    2422#include "defaultdriver.h"
     23#include "indifilterinterface.h"
    2524
    26 class INDI::FilterWheel: public INDI::DefaultDriver
     25/**
     26 * \class INDI::FilterWheel
     27   \brief Class to provide general functionality of a filter wheel device.
     28
     29   Developers need to subclass INDI::FilterWheel to implement any driver for filter wheels within INDI.
     30
     31\author Gerry Rozema, Jasem Mutlaq
     32\see INDI::FilterInterface
     33*/
     34class INDI::FilterWheel: public INDI::DefaultDriver, public INDI::FilterInterface
    2735{
    28     protected:
    29     private:
     36protected:
    3037
    31     public:
    32         FilterWheel();
    33         virtual ~FilterWheel();
     38    FilterWheel();
     39    virtual ~FilterWheel();
    3440
    35         INumberVectorProperty FilterSlotNV;   //  A number vector for filter slot
    36         INumber FilterSlotN[1];
    37 
    38         ITextVectorProperty FilterNameTV; //  A text vector that stores out physical port name
    39         IText FilterNameT[12];
    40 
    41         int MinFilter;
    42         int MaxFilter;
    43         int CurrentFilter;
    44         int TargetFilter;
    45 
     41public:
    4642
    4743        virtual bool initProperties();
    4844        virtual bool updateProperties();
    4945        virtual void ISGetProperties (const char *dev);
     46        virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n);
     47        virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
     48        virtual bool ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n);     
     49        virtual void ISSnoopDevice (XMLEle *root);
    5050
    51         //  Ok, we do need our virtual functions from the base class for processing
    52         //  client requests
    53         //  We process Numbers and text in a filter wheel
    54         virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
    55         virtual bool ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n);
    56         virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { return false; }
     51   protected:
    5752
    58         virtual int SelectFilter(int);
    59         virtual int SelectFilterDone(int);
    60         virtual int QueryFilter();
    61         //int SaveFilterNames();
    62         //int LoadFilterNames();
     53    virtual int QueryFilter();
     54    virtual bool SelectFilter(int);
     55    virtual bool SetFilterNames();
     56    virtual bool GetFilterNames(const char *deviceName, const char* groupName);
    6357
    6458};
  • BAORadio/libindi/libindi/libs/indibase/indifocuser.cpp

    r504 r642  
    11/*******************************************************************************
    2   Copyright(c) 2010 Gerry Rozema. All rights reserved.
     2  Copyright(c) 2011 Gerry Rozema. All rights reserved.
    33
    4   This program is free software; you can redistribute it and/or modify it
    5   under the terms of the GNU General Public License as published by the Free
    6   Software Foundation; either version 2 of the License, or (at your option)
    7   any later version.
     4 This library is free software; you can redistribute it and/or
     5 modify it under the terms of the GNU Library General Public
     6 License version 2 as published by the Free Software Foundation.
    87
    9   This program is distributed in the hope that it will be useful, but WITHOUT
    10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    12   more details.
     8 This library is distributed in the hope that it will be useful,
     9 but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     11 Library General Public License for more details.
    1312
    14   You should have received a copy of the GNU General Public License along with
    15   this program; if not, write to the Free Software Foundation, Inc., 59
    16   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     13 You should have received a copy of the GNU Library General Public License
     14 along with this library; see the file COPYING.LIB.  If not, write to
     15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     16 Boston, MA 02110-1301, USA.
     17*******************************************************************************/
    1718
    18   The full GNU General Public License is included in this distribution in the
    19   file called LICENSE.
    20 *******************************************************************************/
    2119#include "indifocuser.h"
    2220
     
    2523INDI::Focuser::Focuser()
    2624{
    27     //ctor
     25    FocusSpeedNP  = new INumberVectorProperty;
     26    FocusTimerNP  = new INumberVectorProperty;
     27    FocusMotionSP = new ISwitchVectorProperty;
    2828}
    2929
    3030INDI::Focuser::~Focuser()
    3131{
    32     //dtor
     32    delete FocusSpeedNP;
     33    delete FocusTimerNP;
     34    delete FocusMotionSP;
     35
    3336}
    3437
     
    3740    DefaultDriver::initProperties();   //  let the base class flesh in what it wants
    3841
    39     IUFillNumber(&FocusspeedN[0],"FOCUS_SPEED_VALUE","Focus Speed","%3.0f",0.0,255.0,1.0,255.0);
    40     IUFillNumberVector(&FocusspeedNV,FocusspeedN,1,deviceName(),"FOCUS_SPEED","Speed","Main Control",IP_RW,60,IPS_OK);
     42    IUFillNumber(&FocusSpeedN[0],"FOCUS_SPEED_VALUE","Focus Speed","%3.0f",0.0,255.0,1.0,255.0);
     43    IUFillNumberVector(FocusSpeedNP,FocusSpeedN,1,deviceName(),"FOCUS_SPEED","Speed",MAIN_CONTROL_TAB,IP_RW,60,IPS_OK);
    4144
    42     IUFillNumber(&FocustimerN[0],"FOCUS_TIMER_VALUE","Focus Timer","%4.0f",0.0,1000.0,10.0,1000.0);
    43     IUFillNumberVector(&FocustimerNV,FocustimerN,1,deviceName(),"FOCUS_TIMER","Timer","Main Control",IP_RW,60,IPS_OK);
     45    IUFillNumber(&FocusTimerN[0],"FOCUS_TIMER_VALUE","Focus Timer","%4.0f",0.0,1000.0,10.0,1000.0);
     46    IUFillNumberVector(FocusTimerNP,FocusTimerN,1,deviceName(),"FOCUS_TIMER","Timer",MAIN_CONTROL_TAB,IP_RW,60,IPS_OK);
    4447
    45     IUFillSwitch(&FocusmotionS[0],"FOCUS_INWARD","Focus In",ISS_ON);
    46     IUFillSwitch(&FocusmotionS[1],"FOCUS_OUTWARD","Focus Out",ISS_OFF);
    47     IUFillSwitchVector(&FocusmotionSV,FocusmotionS,2,deviceName(),"FOCUS_MOTION","Focus Direction","Main Control",IP_RW,ISR_1OFMANY,60,IPS_OK);
    48 
     48    IUFillSwitch(&FocusMotionS[0],"FOCUS_INWARD","Focus In",ISS_ON);
     49    IUFillSwitch(&FocusMotionS[1],"FOCUS_OUTWARD","Focus Out",ISS_OFF);
     50    IUFillSwitchVector(FocusMotionSP,FocusMotionS,2,deviceName(),"FOCUS_MOTION","Direction",MAIN_CONTROL_TAB,IP_RW,ISR_1OFMANY,60,IPS_OK);
    4951
    5052    return 0;
     
    5456{
    5557    //  First we let our parent populate
    56     IDLog("INDI::Focuser::ISGetProperties %s\n",dev);
    5758    DefaultDriver::ISGetProperties(dev);
    5859
     
    6566    {
    6667        //  Now we add our focusser specific stuff
    67         IDDefSwitch(&FocusmotionSV, NULL);
    68         IDDefNumber(&FocusspeedNV, NULL);
    69         IDDefNumber(&FocustimerNV, NULL);
     68        defineSwitch(FocusMotionSP);
     69        defineNumber(FocusSpeedNP);
     70        defineNumber(FocusTimerNP);
    7071    } else
    7172    {
    72         deleteProperty(FocusmotionSV.name);
    73         deleteProperty(FocusspeedNV.name);
    74         deleteProperty(FocustimerNV.name);
     73        deleteProperty(FocusMotionSP->name);
     74        deleteProperty(FocusSpeedNP->name);
     75        deleteProperty(FocusTimerNP->name);
    7576    }
    7677    return true;
     
    8182{
    8283    //  first check if it's for our device
    83     IDLog("INDI::Focuser::ISNewNumber %s\n",name);
    84     if(strcmp(dev,deviceName())==0) {
     84    if(strcmp(dev,deviceName())==0)
     85    {
    8586        //  This is for our device
    8687        //  Now lets see if it's something we process here
    87         if(strcmp(name,"FOCUS_TIMER")==0) {
     88        if(strcmp(name,"FOCUS_TIMER")==0)
     89        {
    8890            //  Ok, gotta move the focusser now
    89             int dir;
     91            FocusDirection dir;
    9092            int speed;
    9193            int t;
     
    9395            //IDLog(")
    9496            //  first we get all the numbers just sent to us
    95             FocustimerNV.s=IPS_OK;
    96             IUUpdateNumber(&FocustimerNV,values,names,n);
     97            FocusTimerNP->s=IPS_OK;
     98            IUUpdateNumber(FocusTimerNP,values,names,n);
    9799
    98100            //  Now lets find what we need for this move
    99             speed=FocusspeedN[0].value;
    100             if(FocusmotionS[0].s==ISS_ON) dir=1;
    101             else dir=0;
    102             t=FocustimerN[0].value;
     101            speed=FocusSpeedN[0].value;
     102            if(FocusMotionS[0].s==ISS_ON) dir=FOCUS_INWARD;
     103            else dir=FOCUS_OUTWARD;
     104            t=FocusTimerN[0].value;
    103105
    104             Move(dir,speed,t);
     106            if (Move(dir,speed,t) == false)
     107                FocusTimerNP->s = IPS_ALERT;
    105108
    106 
    107             //  Update client display
    108             IDSetNumber(&FocustimerNV,NULL);
     109            IDSetNumber(FocusTimerNP,NULL);
    109110            return true;
    110111        }
    111112
    112113
    113         if(strcmp(name,"FOCUS_SPEED")==0) {
    114 
    115 
    116             FocusspeedNV.s=IPS_OK;
    117             IUUpdateNumber(&FocusspeedNV,values,names,n);
     114        if(strcmp(name,"FOCUS_SPEED")==0)
     115        {
     116            FocusSpeedNP->s=IPS_OK;
     117            IUUpdateNumber(FocusSpeedNP,values,names,n);
    118118
    119119
    120120
    121121            //  Update client display
    122             IDSetNumber(&FocusspeedNV,NULL);
     122            IDSetNumber(FocusSpeedNP,NULL);
    123123            return true;
    124124        }
     
    132132bool INDI::Focuser::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
    133133{
    134     IDLog("Enter IsNewSwitch for %s\n",name);
    135     //for(int x=0; x<n; x++) {
    136     //    IDLog("Switch %s %d\n",names[x],states[x]);
    137     //}
    138134
    139     if(strcmp(dev,deviceName())==0) {
     135    if(strcmp(dev,deviceName())==0)
     136    {
    140137        //  This one is for us
    141         if(strcmp(name,"FOCUS_MOTION")==0) {
     138        if(strcmp(name,"FOCUS_MOTION")==0)
     139        {
    142140            //  client is telling us what to do with focus direction
    143             FocusmotionSV.s=IPS_OK;
    144             IUUpdateSwitch(&FocusmotionSV,states,names,n);
     141            FocusMotionSP->s=IPS_OK;
     142            IUUpdateSwitch(FocusMotionSP,states,names,n);
    145143            //  Update client display
    146             IDSetSwitch(&FocusmotionSV,NULL);
     144            IDSetSwitch(FocusMotionSP,NULL);
    147145
    148146            return true;
     
    155153}
    156154
    157 int INDI::Focuser::Move(int,int,int)
     155bool INDI::Focuser::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
     156{
     157    return DefaultDriver::ISNewText(dev, name, texts, names, n);
     158}
     159
     160void INDI::Focuser::ISSnoopDevice (XMLEle *root)
     161{
     162 return;
     163}
     164
     165bool INDI::Focuser::Move(FocusDirection dir, int speed, int duration)
    158166{
    159167    //  This should be a virtual function, because the low level hardware class
     
    161169    //  but it's much easier early development if the method actually
    162170    //  exists for now
    163     return -1;
     171    return false;
    164172}
    165173
  • BAORadio/libindi/libindi/libs/indibase/indifocuser.h

    r504 r642  
    11/*******************************************************************************
    2   Copyright(c) 2010 Gerry Rozema. All rights reserved.
     2  Copyright(c) 2011 Gerry Rozema. All rights reserved.
    33
    4   This program is free software; you can redistribute it and/or modify it
    5   under the terms of the GNU General Public License as published by the Free
    6   Software Foundation; either version 2 of the License, or (at your option)
    7   any later version.
     4 This library is free software; you can redistribute it and/or
     5 modify it under the terms of the GNU Library General Public
     6 License version 2 as published by the Free Software Foundation.
    87
    9   This program is distributed in the hope that it will be useful, but WITHOUT
    10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    12   more details.
     8 This library is distributed in the hope that it will be useful,
     9 but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     11 Library General Public License for more details.
    1312
    14   You should have received a copy of the GNU General Public License along with
    15   this program; if not, write to the Free Software Foundation, Inc., 59
    16   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    17 
    18   The full GNU General Public License is included in this distribution in the
    19   file called LICENSE.
     13 You should have received a copy of the GNU Library General Public License
     14 along with this library; see the file COPYING.LIB.  If not, write to
     15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     16 Boston, MA 02110-1301, USA.
    2017*******************************************************************************/
    2118
     
    2522#include "defaultdriver.h"
    2623
     24/**
     25 * \class INDI::Focuser
     26   \brief Class to provide general functionality of a focuser device.
     27
     28   Developers need to subclass INDI::Focuser to implement any driver for focusers within INDI.
     29
     30\author Gerry Rozema
     31*/
    2732class INDI::Focuser : public INDI::DefaultDriver
    2833{
    29 
    30     protected:
    31     private:
    32 
    3334    public:
    3435        Focuser();
    3536        virtual ~Focuser();
    3637
    37         INumberVectorProperty FocusspeedNV;
    38         INumber FocusspeedN[1];
    39         ISwitchVectorProperty FocusmotionSV; //  A Switch in the client interface to park the scope
    40         ISwitch FocusmotionS[2];
    41         INumberVectorProperty FocustimerNV;
    42         INumber FocustimerN[1];
    43 
     38        enum FocusDirection { FOCUS_INWARD, FOCUS_OUTWARD };
    4439
    4540        virtual bool initProperties();
    4641        virtual void ISGetProperties (const char *dev);
    47         bool updateProperties();
    48 
    49 
    50         //  Ok, we do need our virtual functions from the base class for processing
    51         //  client requests
    52         //  We process Numbers in a focusser
     42        virtual bool updateProperties();
    5343        virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
    5444        virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n);
     45        virtual bool ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n);
     46        virtual void ISSnoopDevice (XMLEle *root);
    5547
    56         //  And here are the virtual functions we will have for easy overrides
    57         virtual int Move(int, int, int);
     48    protected:
     49
     50        /** \brief Move the focuser in a particular direction with a specific speed for a finite duration.
     51            \param dir Direction of focuser, either FOCUS_INWARD or FOCUS_OUTWARD.
     52            \param speed Speed of focuser if supported by the focuser.
     53            \param duration The timeout in milliseconds before the focus motion halts.
     54            \return True if succssfull, false otherwise.
     55        */
     56        virtual bool Move(FocusDirection dir, int speed, int duration);
     57
     58        INumberVectorProperty *FocusSpeedNP;
     59        INumber FocusSpeedN[1];
     60        ISwitchVectorProperty *FocusMotionSP; //  A Switch in the client interface to park the scope
     61        ISwitch FocusMotionS[2];
     62        INumberVectorProperty *FocusTimerNP;
     63        INumber FocusTimerN[1];
    5864
    5965};
  • BAORadio/libindi/libindi/libs/indibase/inditelescope.cpp

    r504 r642  
    11/*******************************************************************************
    2   Copyright(c) 2010 Gerry Rozema. All rights reserved.
    3 
    4   This program is free software; you can redistribute it and/or modify it
    5   under the terms of the GNU General Public License as published by the Free
    6   Software Foundation; either version 2 of the License, or (at your option)
    7   any later version.
    8 
    9   This program is distributed in the hope that it will be useful, but WITHOUT
    10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    12   more details.
    13 
    14   You should have received a copy of the GNU General Public License along with
    15   this program; if not, write to the Free Software Foundation, Inc., 59
    16   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    17 
    18   The full GNU General Public License is included in this distribution in the
    19   file called LICENSE.
     2  Copyright(c) 2011 Gerry Rozema, Jasem Mutlaq. All rights reserved.
     3
     4 This library is free software; you can redistribute it and/or
     5 modify it under the terms of the GNU Library General Public
     6 License version 2 as published by the Free Software Foundation.
     7
     8 This library is distributed in the hope that it will be useful,
     9 but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     11 Library General Public License for more details.
     12
     13 You should have received a copy of the GNU Library General Public License
     14 along with this library; see the file COPYING.LIB.  If not, write to
     15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     16 Boston, MA 02110-1301, USA.
    2017*******************************************************************************/
     18
    2119
    2220#include "inditelescope.h"
     
    3937{
    4038    //ctor
     39    EqNV = new INumberVectorProperty;
     40    EqReqNV = new INumberVectorProperty;
     41    LocationNV = new INumberVectorProperty;
     42    CoordSV = new ISwitchVectorProperty;
     43    ParkSV = new ISwitchVectorProperty;
     44    PortTV = new ITextVectorProperty;
     45    MovementNSSP = new ISwitchVectorProperty;
     46    MovementWESP = new ISwitchVectorProperty;
     47    ConfigSV = new ISwitchVectorProperty;
     48
    4149}
    4250
    4351INDI::Telescope::~Telescope()
    4452{
    45     //dtor
     53    delete EqNV;
     54    delete EqReqNV;
     55    delete LocationNV;
     56    delete CoordSV;
     57    delete ParkSV;
     58    delete PortTV;
     59    delete MovementNSSP;
     60    delete MovementWESP;
     61    delete ConfigSV;
    4662}
    4763
     
    4965{
    5066    DefaultDriver::initProperties();
    51 
    52     EqNV = new INumberVectorProperty;
    5367
    5468    IUFillNumber(&EqN[0],"RA","RA (hh:mm:ss)","%010.6m",0,24,0,0);
    5569    IUFillNumber(&EqN[1],"DEC","DEC (dd:mm:ss)","%010.6m",-90,90,0,0);
    56     IUFillNumberVector(EqNV,EqN,2,deviceName(),"EQUATORIAL_EOD_COORD","Eq. Coordinates","Main Control",IP_RO,60,IPS_IDLE);
    57 
    58     EqReqNV = new INumberVectorProperty;
     70    IUFillNumberVector(EqNV,EqN,2,deviceName(),"EQUATORIAL_EOD_COORD","Eq. Coordinates",MAIN_CONTROL_TAB,IP_RO,60,IPS_IDLE);
    5971
    6072    IUFillNumber(&EqReqN[0],"RA","RA (hh:mm:ss)","%010.6m",0,24,0,0);
    6173    IUFillNumber(&EqReqN[1],"DEC","DEC (dd:mm:ss)","%010.6m",-90,90,0,0);
    62     IUFillNumberVector(EqReqNV,EqReqN,2,deviceName(),"EQUATORIAL_EOD_COORD_REQUEST","GOTO","Controls",IP_WO,60,IPS_IDLE);
    63 
    64     LocationNV = new INumberVectorProperty;
     74    IUFillNumberVector(EqReqNV,EqReqN,2,deviceName(),"EQUATORIAL_EOD_COORD_REQUEST","GOTO",MAIN_CONTROL_TAB,IP_WO,60,IPS_IDLE);
    6575
    6676    IUFillNumber(&LocationN[0],"LAT","Lat (dd:mm:ss)","%010.6m",-90,90,0,0.0);
    67     IUFillNumber(&LocationN[1],"LONG","Lon (dd:mm:ss)","%010.6m",0,360,0,0.0 );
    68     IUFillNumberVector(LocationNV,LocationN,2,deviceName(),"GEOGRAPHIC_COORD","Scope Location","Location",IP_RW,60,IPS_OK);
    69 
    70     CoordSV = new ISwitchVectorProperty;
     77    IUFillNumber(&LocationN[1],"LONG","Lon (dd:mm:ss)","%010.6m",-180,180,0,0.0 );
     78    IUFillNumberVector(LocationNV,LocationN,2,deviceName(),"GEOGRAPHIC_COORD","Scope Location",SITE_TAB,IP_RW,60,IPS_OK);
    7179
    7280    IUFillSwitch(&CoordS[0],"TRACK","Track",ISS_OFF);
    7381    IUFillSwitch(&CoordS[1],"SLEW","Slew",ISS_OFF);
    7482    IUFillSwitch(&CoordS[2],"SYNC","Sync",ISS_OFF);
    75     IUFillSwitchVector(CoordSV,CoordS,3,deviceName(),"ON_COORD_SET","On Set","Controls",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
    76 
    77     ParkSV = new ISwitchVectorProperty;
     83    IUFillSwitchVector(CoordSV,CoordS,3,deviceName(),"ON_COORD_SET","On Set",MAIN_CONTROL_TAB,IP_RW,ISR_1OFMANY,60,IPS_IDLE);
     84
     85    IUFillSwitch(&ConfigS[0], "CONFIG_LOAD", "Load", ISS_OFF);
     86    IUFillSwitch(&ConfigS[1], "CONFIG_SAVE", "Save", ISS_OFF);
     87    IUFillSwitch(&ConfigS[2], "CONFIG_DEFAULT", "Default", ISS_OFF);
     88    IUFillSwitchVector(ConfigSV, ConfigS, 3, deviceName(), "CONFIG_PROCESS", "Configuration", "Options", IP_RW, ISR_1OFMANY, 60, IPS_IDLE);
     89
    7890
    7991    IUFillSwitch(&ParkS[0],"PARK","Park",ISS_OFF);
    80     IUFillSwitchVector(ParkSV,ParkS,1,deviceName(),"TELESCOPE_PARK","Park","Controls",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
    81 
    82     PortTV = new ITextVectorProperty;
     92    IUFillSwitchVector(ParkSV,ParkS,1,deviceName(),"TELESCOPE_PARK","Park",MAIN_CONTROL_TAB,IP_RW,ISR_1OFMANY,60,IPS_IDLE);
    8393
    8494    IUFillText(&PortT[0],"PORT","Port","/dev/ttyUSB0");
    85     IUFillTextVector(PortTV,PortT,1,deviceName(),"DEVICE_PORT","Ports","Options",IP_RW,60,IPS_IDLE);
     95    IUFillTextVector(PortTV,PortT,1,deviceName(),"DEVICE_PORT","Ports",OPTIONS_TAB,IP_RW,60,IPS_IDLE);
     96
     97    IUFillSwitch(&MovementNSS[MOTION_NORTH], "MOTION_NORTH", "North", ISS_OFF);
     98    IUFillSwitch(&MovementNSS[MOTION_SOUTH], "MOTION_SOUTH", "South", ISS_OFF);
     99    IUFillSwitchVector(MovementNSSP, MovementNSS, 2, deviceName(),"TELESCOPE_MOTION_NS", "North/South", MOTION_TAB, IP_RW, ISR_1OFMANY, 60, IPS_IDLE);
     100
     101    IUFillSwitch(&MovementWES[MOTION_WEST], "MOTION_WEST", "West", ISS_OFF);
     102    IUFillSwitch(&MovementWES[MOTION_EAST], "MOTION_EAST", "East", ISS_OFF);
     103    IUFillSwitchVector(MovementWESP, MovementWES, 2, deviceName(),"TELESCOPE_MOTION_WE", "West/East", MOTION_TAB, IP_RW, ISR_1OFMANY, 60, IPS_IDLE);
    86104
    87105    TrackState=SCOPE_PARKED;
     
    96114
    97115    //  We may need the port set before we can connect
    98     //IDDefText(&PortTV,NULL);
     116    IDDefText(PortTV,NULL);
    99117    //LoadConfig();
    100118
     
    107125        defineNumber(LocationNV);
    108126        defineSwitch(ParkSV);
     127        defineSwitch(MovementNSSP);
     128        defineSwitch(MovementWESP);
     129                defineSwitch(ConfigSV);
     130
    109131    }
    110132    return;
     
    113135bool INDI::Telescope::updateProperties()
    114136{
     137    defineText(PortTV);
    115138    if(isConnected())
    116139    {
    117140        //  Now we add our telescope specific stuff
    118         //IDLog("INDI::Telescope adding properties\n");
    119141        defineSwitch(CoordSV);
    120142        defineNumber(EqNV);
    121143        defineNumber(EqReqNV);
    122         //IDDefText(&PortTV,NULL);
     144        defineSwitch(MovementNSSP);
     145        defineSwitch(MovementWESP);
    123146        defineNumber(LocationNV);
    124147        defineSwitch(ParkSV);
     148
    125149    } else
    126150    {
     
    129153        deleteProperty(EqNV->name);
    130154        deleteProperty(EqReqNV->name);
    131         //DeleteProperty(PortTV.name);
     155        deleteProperty(MovementNSSP->name);
     156        deleteProperty(MovementWESP->name);
    132157        deleteProperty(LocationNV->name);
    133158        deleteProperty(ParkSV->name);
    134159
    135         initProperties();
    136     }
     160        //initProperties();
     161    }
     162        defineSwitch(ConfigSV);
     163
    137164    return true;
    138165}
    139166
    140 int INDI::Telescope::NewRaDec(double ra,double dec)
     167bool INDI::Telescope::saveConfigItems(FILE *fp)
     168{
     169
     170        IUSaveConfigNumber(fp,LocationNV);
     171    return true;
     172}
     173
     174void INDI::Telescope::NewRaDec(double ra,double dec)
    141175{
    142176    //  Lets set our eq values to these numbers
    143177    //  which came from the hardware
    144     EqN[0].value=ra;
    145     EqN[1].value=dec;
     178    static int last_state=-1;
    146179
    147180    if (TrackState == SCOPE_TRACKING && EqReqNV->s != IPS_OK)
     
    150183        IDSetNumber(EqReqNV, NULL);
    151184    }
    152     if ( (TrackState == SCOPE_PARKED || TrackState == SCOPE_IDLE) && EqReqNV->s != IPS_IDLE)
     185    else if ( (TrackState == SCOPE_PARKED || TrackState == SCOPE_IDLE) && EqReqNV->s != IPS_IDLE)
    153186    {
    154187        EqReqNV->s = IPS_IDLE;
     
    156189    }
    157190
    158     return 0;
     191    //IDLog("newRA DEC RA %g - DEC %g --- EqN[0] %g --- EqN[1] %g --- EqN.state %d\n", ra, dec, EqN[0].value, EqN[1].value, EqNV->s);
     192    if (EqN[0].value != ra || EqN[1].value != dec || EqNV->s != last_state)
     193    {
     194      //  IDLog("Not equal , send update to client...\n");
     195        EqN[0].value=ra;
     196        EqN[1].value=dec;
     197        last_state = EqNV->s;
     198        IDSetNumber(EqNV, NULL);
     199    }
     200
    159201}
    160202
     
    176218    //  if we get here, our mount doesn't support sync
    177219    IDMessage(deviceName(),"Mount does not support Sync");
     220    return false;
     221}
     222
     223bool INDI::Telescope::MoveNS(TelescopeMotionNS dir)
     224{
     225    IDMessage(deviceName(),"Mount does not support North/South motion");
     226    IUResetSwitch(MovementNSSP);
     227    MovementNSSP->s = IPS_IDLE;
     228    IDSetSwitch(MovementNSSP, NULL);
     229    return false;
     230}
     231
     232bool INDI::Telescope::MoveWE(TelescopeMotionWE dir)
     233{
     234    IDMessage(deviceName(),"Mount does not support West/East motion");
     235    IUResetSwitch(MovementWESP);
     236    MovementWESP->s = IPS_IDLE;
     237    IDSetSwitch(MovementWESP, NULL);
    178238    return false;
    179239}
     
    328388            Park();
    329389        }
     390
     391        if(strcmp(name,"TELESCOPE_MOTION_NS")==0)
     392        {
     393            IUUpdateSwitch(MovementNSSP,states,names,n);
     394
     395            MovementNSSP->s = IPS_BUSY;
     396
     397            if (MovementNSS[MOTION_NORTH].s == ISS_ON)
     398                MoveNS(MOTION_NORTH);
     399            else
     400                MoveNS(MOTION_SOUTH);
     401
     402            return true;
     403        }
     404
     405        if(strcmp(name,"TELESCOPE_MOTION_WE")==0)
     406        {
     407            IUUpdateSwitch(MovementWESP,states,names,n);
     408
     409            MovementWESP->s = IPS_BUSY;
     410
     411            if (MovementWES[MOTION_WEST].s == ISS_ON)
     412                MoveWE(MOTION_WEST);
     413            else
     414                MoveWE(MOTION_EAST);
     415
     416            return true;
     417        }
     418
    330419    }
    331420
     
    334423}
    335424
     425
    336426bool INDI::Telescope::Connect()
    337427{
    338428    //  Parent class is wanting a connection
    339     //IDLog("INDI::Telescope calling connect with %s\n",PortT[0].text);
     429    if (isDebug())
     430        IDLog("INDI::Telescope arrived in connect with %s\n",PortT[0].text);
    340431    bool rc=false;
    341432
    342433    if(isConnected()) return true;
    343434
    344     //IDLog("Calling Connect\n");
     435
     436    if (isDebug())
     437        IDLog("Telescope Calling Connect\n");
    345438
    346439    rc=Connect(PortT[0].text);
     440
     441    if (isDebug())
     442        IDLog("Telescope Connect returns %d\n",rc);
    347443
    348444    if(rc)
     
    351447}
    352448
     449
    353450bool INDI::Telescope::Connect(const char *port)
    354451{
     
    361458    bool rc;
    362459
    363 
    364     if ( (connectrc = tty_connect(port, B9600, 8, 0, 1, &PortFD)) != TTY_OK)
     460        IDLog("Indi Telescope connecting to %s\n",port);
     461
     462    if ( (connectrc = tty_connect(port, 9600, 8, 0, 1, &PortFD)) != TTY_OK)
    365463    {
    366464        tty_error_msg(connectrc, errorMsg, MAXRBUF);
    367465
    368         if (isDebug())
     466        //if (isDebug())
    369467            IDLog("Failed to connect o port %s. Error: %s", port, errorMsg);
    370468        IDMessage(deviceName(), "Failed to connect to port %s. Error: %s", port, errorMsg);
     
    373471
    374472    }
    375 
     473        IDLog("Port Fd %d\n",PortFD);
    376474    /* Flush the input (read) buffer */
    377475
    378     tcflush(PortFD,TCIOFLUSH);
     476    //tcflush(PortFD,TCIOFLUSH);
    379477
    380478    /* Test connection */
     
    401499    //Connected=false;
    402500
     501        IDLog("IndiTelescope Disconnect\n");
     502
    403503    close(PortFD);
    404504    IDMessage(deviceName(),"Telescope is offline.");
     
    410510void INDI::Telescope::TimerHit()
    411511{
    412     //IDLog("Timer Hit\n");
     512    //IDLog("Telescope Timer Hit\n");
    413513    if(isConnected())
    414514    {
     
    417517        rc=ReadScopeStatus();
    418518        //IDLog("TrackState after read is %d\n",TrackState);
    419         if(rc)
    420         {
    421             //  read was good
    422             switch(TrackState)
    423             {
    424               case SCOPE_IDLE:
    425               case SCOPE_PARKED:
    426                 EqNV->s=IPS_IDLE;
    427                 break;
    428 
    429              case SCOPE_SLEWING:
    430              case SCOPE_PARKING:
    431                 EqNV->s=IPS_BUSY;
    432                 break;
    433 
    434             case SCOPE_TRACKING:
    435                 EqNV->s=IPS_OK;
    436                 break;
    437             }
    438         } else
     519        if(rc == false)
    439520        {
    440521            //  read was not good
    441522            EqNV->s=IPS_ALERT;
    442         }
    443         //IDLog("IsConnected, re-arm timer\n");
    444         //  Now update the Client data
    445         IDSetNumber(EqNV,NULL);
     523            IDSetNumber(EqNV, NULL);
     524        }     
     525
    446526        SetTimer(POLLMS);
    447527    }
  • BAORadio/libindi/libindi/libs/indibase/inditelescope.h

    r504 r642  
    11/*******************************************************************************
    2   Copyright(c) 2010 Gerry Rozema. All rights reserved.
     2  Copyright(c) 2011 Gerry Rozema, Jasem Mutlaq. All rights reserved.
    33
    4   This program is free software; you can redistribute it and/or modify it
    5   under the terms of the GNU General Public License as published by the Free
    6   Software Foundation; either version 2 of the License, or (at your option)
    7   any later version.
     4 This library is free software; you can redistribute it and/or
     5 modify it under the terms of the GNU Library General Public
     6 License version 2 as published by the Free Software Foundation.
    87
    9   This program is distributed in the hope that it will be useful, but WITHOUT
    10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    12   more details.
     8 This library is distributed in the hope that it will be useful,
     9 but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     11 Library General Public License for more details.
    1312
    14   You should have received a copy of the GNU General Public License along with
    15   this program; if not, write to the Free Software Foundation, Inc., 59
    16   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    17 
    18   The full GNU General Public License is included in this distribution in the
    19   file called LICENSE.
     13 You should have received a copy of the GNU Library General Public License
     14 along with this library; see the file COPYING.LIB.  If not, write to
     15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     16 Boston, MA 02110-1301, USA.
    2017*******************************************************************************/
    2118
     
    2522#include "defaultdriver.h"
    2623
     24/**
     25 * \class INDI::Telescope
     26   \brief Class to provide general functionality of a telescope device.
     27
     28   Developers need to subclass INDI::Telescope to implement any driver for telescopes within INDI.
     29
     30   Implementing a basic telescope driver involves the child class performing the following steps:
     31   <ul>
     32   <li>If the telescope has additional properties, the child class should override initProperties and initilize the respective additional properties.</li>
     33   <li>Once the parent class calls Connect(), the child class attempts to connect to the telescope and return either success of failure</li>
     34   <li>INDI::Telescope calls updateProperties() to enable the child class to define which properties to send to the client upon connection</li>
     35   <li>INDI::Telescope calls ReadScopeStatus() to check the link to the telescope and update its state and position. The child class should call newRaDec() whenever
     36   a new value is read from the telescope.</li>
     37   <li>The child class should implmenet Goto() and Sync(), and Park() if applicable.</li>
     38   <li>INDI::Telescope calls disconnect() when the client request a disconnection. The child class should remove any additional properties it defined in updateProperties() if applicable</li>
     39   </ul>
     40
     41\author Gerry Rozema, Jasem Mutlaq
     42\see TelescopeSimulator and SynScan drivers for examples of implementations of INDI::Telescope.
     43*/
    2744class INDI::Telescope : public INDI::DefaultDriver
    2845{
    29     protected:
    30         //bool Connected;
    31 
    3246    private:
    3347
     
    3751
    3852        enum TelescopeStatus { SCOPE_IDLE, SCOPE_SLEWING, SCOPE_TRACKING, SCOPE_PARKING, SCOPE_PARKED };
     53        enum TelescopeMotionNS { MOTION_NORTH, MOTION_SOUTH };
     54        enum TelescopeMotionWE { MOTION_WEST, MOTION_EAST };
     55
     56        virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
     57        virtual bool ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n);
     58        virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n);
     59        virtual void ISGetProperties (const char *dev);
     60
     61        /** \brief Called to initialize basic properties required all the time */
     62        virtual bool initProperties();
     63        /** \brief Called when connected state changes, to add/remove properties */
     64        virtual bool updateProperties();
     65
     66        /** \brief Called when setTimer() time is up */
     67        virtual void TimerHit();
     68
     69        /** \brief Connect to the telescope.
     70          \return True if connection is successful, false otherwise
     71        */
     72        virtual bool Connect();
     73
     74        /** \brief Disconnect from telescope
     75            \return True if successful, false otherwise */
     76        virtual bool Disconnect();
     77
     78        /** \brief INDI::Telescope implementation of Connect() assumes 9600 baud, 8 bit word, even parity, and no stop bit. Override function if communication paramaters
     79          are different
     80          \param port Port to connect to
     81          \return True if connection is successful, false otherwise
     82          \warning Do not call this function directly, it is called by INDI::Telescope Connect() function.
     83        */
     84        virtual bool Connect(const char *port);
     85
     86        protected:
     87
     88        virtual bool saveConfigItems(FILE *fp);
     89
     90        /** \brief The child class calls this function when it has updates */
     91        void NewRaDec(double ra,double dec);
     92
     93        /** \brief Read telescope status.
     94         This function checks the following:
     95         <ol>
     96           <li>Check if the link to the telescope is alive.</li>
     97           <li>Update telescope status: Idle, Slewing, Parking..etc.</li>
     98           <li>Read coordinates</li>
     99         </ol>
     100          \return True if reading scope status is OK, false if an error is encounterd.
     101          \note This function is not implemented in INDI::Telescope, it must be implemented in the child class */
     102        virtual bool ReadScopeStatus();
     103
     104        /** \brief Move the scope to the supplied RA and DEC coordinates
     105            \return True if successful, false otherewise
     106            \note This function is not implemented in INDI::Telescope, it must be implemented in the child class
     107        */
     108        virtual bool Goto(double ra,double dec);
     109
     110        /** \brief Set the telescope current RA and DEC coordinates to the supplied RA and DEC coordinates
     111            \return True if successful, false otherewise
     112            \note This function is not implemented in INDI::Telescope, it must be implemented in the child class
     113        */
     114        virtual bool Sync(double ra,double dec);
     115
     116        /** \brief Move the telescope in the direction dir.
     117            \return True if successful, false otherewise
     118            \note This function is not implemented in INDI::Telescope, it must be implemented in the child class
     119        */
     120        virtual bool MoveNS(TelescopeMotionNS dir);
     121
     122        /** \brief Move the telescope in the direction dir.
     123            \return True if successful, false otherewise
     124            \note This function is not implemented in INDI::Telescope, it must be implemented in the child class
     125        */
     126        virtual bool MoveWE(TelescopeMotionWE dir);
     127
     128        /** \brief Part the telescope to its home position.
     129            \return True if successful, false otherewise
     130            \note This function is not implemented in INDI::Telescope, it must be implemented in the child class
     131        */
     132        virtual bool Park();
     133
     134
     135        //  Since every mount I know of actually uses a serial port for control
     136        //  We put the serial helper into the base telescope class
     137        //  One less piece to worry about in the hardware specific
     138        //  low level stuff
     139        int PortFD;
     140
     141        //  This is a variable filled in by the ReadStatus telescope
     142        //  low level code, used to report current state
     143        //  are we slewing, tracking, or parked.
     144        TelescopeStatus TrackState;
    39145
    40146        //  All telescopes should produce equatorial co-ordinates
     
    49155        ISwitch CoordS[3];              //  On a coord_set message, sync, or slew
    50156
     157        ISwitchVectorProperty *ConfigSV; //  A switch vector that stores how we should readct
     158        ISwitch ConfigS[3];              //  On a coord_set message, sync, or slew
     159
    51160        INumberVectorProperty *LocationNV;   //  A number vector that stores lattitude and longitude
    52161        INumber LocationN[2];
     
    55164        ISwitch ParkS[1];
    56165
    57         //  I dont know of any telescopes that dont
    58         //  need a port for connection
    59         //  So lets put all the port connect framework
    60         //  into our generic telescope super class
    61166        ITextVectorProperty *PortTV; //  A text vector that stores out physical port name
    62167        IText PortT[1];
    63168
     169        ISwitch MovementNSS[2];     // A switch for North/South motion
     170        ISwitchVectorProperty *MovementNSSP;
    64171
    65         //  Ok, we do need our virtual functions from the base class for processing
    66         //  client requests
    67         //  We process numbers,switches and text in the telescope
    68         //  These are the base IndiDevice overrides we process
    69         virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
    70         virtual bool ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n);
    71         virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n);
    72         virtual void ISGetProperties (const char *dev);
     172        ISwitch MovementWES[2];     // A switch for West/East motion
     173        ISwitchVectorProperty *MovementWESP;
    73174
    74         //  overrides of base class virtual functions
    75         //  that are specific to our way of implementing Indi
    76         virtual bool initProperties();      //  Called to initialize basic properties required all the time
    77         virtual bool updateProperties();    //  Called when connected state changes, to add/remove properties
    78 
    79         virtual void TimerHit();
    80         virtual bool Connect();
    81         virtual bool Disconnect();
    82 
    83         virtual bool Connect(const char *);
    84 
    85 
    86         //  Since every mount I know of actually uses a serial port for control
    87         //  We put the serial helper into the base telescope class
    88         //  One less piece to worry about in the hardware specific
    89         //  low level stuff
    90         int PortFD;
    91 
    92 
    93         //  This is a variable filled in by the ReadStatus telescope
    94         //  low level code, used to report current state
    95         //  are we slewing, tracking, or parked.
    96         int TrackState;
    97 
    98 
    99         //  These functions are telescope specific
    100         //  and meant to make life really easy for deriving
    101         //  hardware specific telescope classes
    102         int NewRaDec(double,double);    //  The child class will call this when it has updates
    103 
    104 
    105         //  And these are the hardware specific functions our children need to override
    106         //  They are not pure virtual, because, not all functions are relavent for all types
    107         //  of mount, ie, a Goto is not relavent for a Push-to mount
    108 
    109         /** \brief Read telescope status.
    110          This function checks the following:
    111          <ol>
    112            <li>Check if the link to the telescope is alive.</li>
    113            <li>Update telescope status: Idle, Slewing, Parking..etc.</li>
    114            <li>Read coordinates</li>
    115          </ol>
    116           \return True if reading scope status is OK, false if an error is encounterd. */
    117         virtual bool ReadScopeStatus();
    118 
    119         virtual bool Goto(double ra,double dec);
    120         virtual bool Sync(double ra,double dec);
    121         virtual bool Park();
    122175
    123176};
  • BAORadio/libindi/libindi/libs/indibase/indiusbdevice.cpp

    r504 r642  
    11/*******************************************************************************
    2   Copyright(c) 2010 Gerry Rozema. All rights reserved.
     2  Copyright(c) 2011 Gerry Rozema. All rights reserved.
    33
    4   This program is free software; you can redistribute it and/or modify it
    5   under the terms of the GNU General Public License as published by the Free
    6   Software Foundation; either version 2 of the License, or (at your option)
    7   any later version.
     4 This library is free software; you can redistribute it and/or
     5 modify it under the terms of the GNU Library General Public
     6 License version 2 as published by the Free Software Foundation.
    87
    9   This program is distributed in the hope that it will be useful, but WITHOUT
    10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    12   more details.
     8 This library is distributed in the hope that it will be useful,
     9 but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     11 Library General Public License for more details.
    1312
    14   You should have received a copy of the GNU General Public License along with
    15   this program; if not, write to the Free Software Foundation, Inc., 59
    16   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    17 
    18   The full GNU General Public License is included in this distribution in the
    19   file called LICENSE.
     13 You should have received a copy of the GNU Library General Public License
     14 along with this library; see the file COPYING.LIB.  If not, write to
     15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     16 Boston, MA 02110-1301, USA.
    2017*******************************************************************************/
    2118#include "indiusbdevice.h"
     
    149146}
    150147
    151 int INDI::USBDevice::ReadBulk(char *buf,int c,int timeout)
     148int INDI::USBDevice::ReadBulk(char *buf,int nbytes,int timeout)
    152149{
    153150        int rc;
    154151
    155152        //rc=usb_interrupt_read(usb_handle,InputEndpoint,buf,c,timeout);
    156         rc=usb_bulk_read(usb_handle,InputEndpoint,buf,c,timeout);
     153        rc=usb_bulk_read(usb_handle,InputEndpoint,buf,nbytes,timeout);
    157154        return rc;
    158155
    159156}
    160157
    161 int INDI::USBDevice::WriteBulk(char *buf,int c,int timeout)
     158int INDI::USBDevice::WriteBulk(char *buf,int nbytes,int timeout)
    162159{
    163160        int rc;
     
    165162        //printf("Writing %02x to endpoint %d\n",buf[0],OutputEndpoint);
    166163        //rc=usb_interrupt_write(usb_handle,OutputEndpoint,buf,c,timeout);
    167         rc=usb_bulk_write(usb_handle,OutputEndpoint,buf,c,timeout);
     164        rc=usb_bulk_write(usb_handle,OutputEndpoint,buf,nbytes,timeout);
    168165        return rc;
    169166
  • BAORadio/libindi/libindi/libs/indibase/indiusbdevice.h

    r504 r642  
    11/*******************************************************************************
    2   Copyright(c) 2010 Gerry Rozema. All rights reserved.
     2  Copyright(c) 2011 Gerry Rozema. All rights reserved.
    33
    4   This program is free software; you can redistribute it and/or modify it
    5   under the terms of the GNU General Public License as published by the Free
    6   Software Foundation; either version 2 of the License, or (at your option)
    7   any later version.
     4 This library is free software; you can redistribute it and/or
     5 modify it under the terms of the GNU Library General Public
     6 License version 2 as published by the Free Software Foundation.
    87
    9   This program is distributed in the hope that it will be useful, but WITHOUT
    10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    12   more details.
     8 This library is distributed in the hope that it will be useful,
     9 but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     11 Library General Public License for more details.
    1312
    14   You should have received a copy of the GNU General Public License along with
    15   this program; if not, write to the Free Software Foundation, Inc., 59
    16   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    17 
    18   The full GNU General Public License is included in this distribution in the
    19   file called LICENSE.
     13 You should have received a copy of the GNU Library General Public License
     14 along with this library; see the file COPYING.LIB.  If not, write to
     15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     16 Boston, MA 02110-1301, USA.
    2017*******************************************************************************/
    2118
     
    3431#include "indibase.h"
    3532
     33/**
     34 * \class INDI::USBDevice
     35   \brief Class to provide general functionality of a generic USB device.
     36
     37   Developers need to subclass INDI::USBDevice to implement any driver within INDI that requires direct read/write/control over USB.
     38
     39\author Gerry Rozema
     40\see Starlight Xpress INDI CCD driver for an example implementation of INDI::USBDevice
     41*/
    3642class INDI::USBDevice
    3743{
     
    5662        int ControlMessage();
    5763
    58         int WriteBulk(char *,int,int);
    59         int ReadBulk(char *,int,int);
     64        int WriteBulk(char *buf,int nbytes,int timeout);
     65        int ReadBulk(char *buf,int nbytes,int timeout);
    6066        int FindEndpoints();
    6167        int Open();
  • BAORadio/libindi/libindi/libs/indicom.c

    r504 r642  
    147147        default:
    148148            printf ("fs_sexa: unknown fracbase: %d\n", fracbase);
    149             exit(1);
     149            return -1;
    150150        }
    151151
     
    389389}
    390390
    391 #ifdef BSD
     391#if defined(BSD) && !defined(__GNU__)
    392392// BSD - OSX version
    393393int tty_connect(const char *device, int bit_rate, int word_size, int parity, int stop_bits, int *fd)
     
    949949        default:
    950950            fprintf (stderr, "Impossible IPState %d\n", s);
    951             exit(1);
     951            return NULL;
    952952        }
    953953}
     
    10071007        default:
    10081008            fprintf (stderr, "Impossible ISState %d\n", s);
     1009            return NULL;
    10091010        }
    10101011}
     
    10201021        default:
    10211022            fprintf (stderr, "Impossible ISRule %d\n", r);
     1023            return NULL;
    10221024        }
    10231025}
     
    10331035        default:
    10341036            fprintf (stderr, "Impossible IPerm %d\n", p);
     1037            return NULL;
    10351038        }
    10361039}
  • BAORadio/libindi/libindi/libs/lilxml.c

    r490 r642  
    1515    You should have received a copy of the GNU Lesser General Public
    1616    License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     17    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1818
    1919#endif
     
    2727 */
    2828
     29#include <stdio.h>
    2930#include <stdlib.h>
    3031#include <string.h>
     
    4142#define MINMEM  64                      /* starting string length */
    4243
    43 static int oneXMLchar (LilXML *lp, int c, char errmsg[]);
     44static int oneXMLchar (LilXML *lp, int c, char ynot[]);
    4445static void initParser(LilXML *lp);
    4546static void pushXMLEle(LilXML *lp);
     
    111112static char entities[] = "&<>'\"";
    112113
    113 /* default memory managers, override with indi_xmlMalloc() */
     114/* default memory managers, override with lilxmlMalloc() */
    114115static void *(*mymalloc)(size_t size) = malloc;
    115116static void *(*myrealloc)(void *ptr, size_t size) = realloc;
     
    120121 */
    121122void
    122 indi_xmlMalloc (void *(*newmalloc)(size_t size),
    123            void *(*newrealloc)(void *ptr, size_t size),
    124            void (*newfree)(void *ptr))
    125 {
    126         mymalloc = newmalloc;
    127         myrealloc = newrealloc;
    128         myfree = newfree;
     123lilxmlMalloc (void *(*newmalloc)(size_t size),
     124           void *(*newrealloc)(void *ptr, size_t size),
     125           void (*newfree)(void *ptr))
     126{
     127        mymalloc = newmalloc;
     128        myrealloc = newrealloc;
     129        myfree = newfree;
    129130}
    130131
     
    133134newLilXML ()
    134135{
    135         LilXML *lp = (LilXML *) moremem (NULL, sizeof(LilXML));
    136         memset (lp, 0, sizeof(LilXML));
    137         initParser(lp);
    138         return (lp);
     136        LilXML *lp = (LilXML *) moremem (NULL, sizeof(LilXML));
     137        memset (lp, 0, sizeof(LilXML));
     138        initParser(lp);
     139        return (lp);
    139140}
    140141
     
    143144delLilXML (LilXML *lp)
    144145{
    145         delXMLEle (lp->ce);
    146         freeString (&lp->endtag);
    147         (*myfree) (lp);
     146        delXMLEle (lp->ce);
     147        freeString (&lp->endtag);
     148        (*myfree) (lp);
    148149}
    149150
     
    152153delXMLEle (XMLEle *ep)
    153154{
    154         int i;
    155 
    156         /* benign if NULL */
    157         if (!ep)
    158             return;
    159 
    160         /* delete all parts of ep */
    161         freeString (&ep->tag);
    162         freeString (&ep->pcdata);
    163         if (ep->at) {
    164             for (i = 0; i < ep->nat; i++)
    165                 freeAtt (ep->at[i]);
    166             (*myfree) (ep->at);
    167         }
    168         if (ep->el) {
    169             for (i = 0; i < ep->nel; i++) {
    170                 /* forget parent so deleting doesn't modify _this_ el[] */
    171                 ep->el[i]->pe = NULL;
    172 
    173                 delXMLEle (ep->el[i]);
    174             }
    175             (*myfree) (ep->el);
    176         }
    177 
    178         /* remove from parent's list if known */
    179         if (ep->pe) {
    180             XMLEle *pe = ep->pe;
    181             for (i = 0; i < pe->nel; i++) {
    182                 if (pe->el[i] == ep) {
    183                     memmove (&pe->el[i], &pe->el[i+1],
    184                                               (--pe->nel-i)*sizeof(XMLEle*));
    185                     break;
    186                 }
    187             }
    188         }
    189 
    190         /* delete ep itself */
    191         (*myfree) (ep);
     155        int i;
     156
     157        /* benign if NULL */
     158        if (!ep)
     159            return;
     160
     161        /* delete all parts of ep */
     162        freeString (&ep->tag);
     163        freeString (&ep->pcdata);
     164        if (ep->at) {
     165            for (i = 0; i < ep->nat; i++)
     166                freeAtt (ep->at[i]);
     167            (*myfree) (ep->at);
     168        }
     169        if (ep->el) {
     170            for (i = 0; i < ep->nel; i++) {
     171                /* forget parent so deleting doesn't modify _this_ el[] */
     172                ep->el[i]->pe = NULL;
     173
     174                delXMLEle (ep->el[i]);
     175            }
     176            (*myfree) (ep->el);
     177        }
     178
     179        /* remove from parent's list if known */
     180        if (ep->pe) {
     181            XMLEle *pe = ep->pe;
     182            for (i = 0; i < pe->nel; i++) {
     183                if (pe->el[i] == ep) {
     184                    memmove (&pe->el[i], &pe->el[i+1],
     185                                              (--pe->nel-i)*sizeof(XMLEle*));
     186                    break;
     187                }
     188            }
     189        }
     190
     191        /* delete ep itself */
     192        (*myfree) (ep);
    192193}
    193194
    194195/* process one more character of an XML file.
    195196 * when find closure with outter element return root of complete tree.
    196  * when find error return NULL with reason in errmsg[].
    197  * when need more return NULL with errmsg[0] = '\0'.
     197 * when find error return NULL with reason in ynot[].
     198 * when need more return NULL with ynot[0] = '\0'.
    198199 * N.B. it is up to the caller to delete any tree returned with delXMLEle().
    199200 */
    200201XMLEle *
    201 readXMLEle (LilXML *lp, int newc, char errmsg[])
    202 {
    203         XMLEle *root;
    204         int s;
    205 
    206         /* start optimistic */
    207         errmsg[0] = '\0';
    208 
    209         /* EOF? */
    210         if (newc == 0) {
    211             sprintf (errmsg, "Line %d: early XML EOF", lp->ln);
    212             initParser(lp);
    213             return (NULL);
    214         }
    215 
    216         /* new line? */
    217         if (newc == '\n')
    218             lp->ln++;
    219 
    220         /* skip comments and declarations. requires 1 char history */
    221         if (!lp->skipping && lp->lastc == '<' && (newc == '?' || newc == '!')) {
    222             lp->skipping = 1;
    223             lp->lastc = newc;
    224             return (NULL);
    225         }
    226         if (lp->skipping) {
    227             if (newc == '>')
    228                 lp->skipping = 0;
    229             lp->lastc = newc;
    230             return (NULL);
    231         }
    232         if (newc == '<') {
    233             lp->lastc = '<';
    234             return (NULL);
    235         }
    236 
    237         /* do a pending '<' first then newc */
    238         if (lp->lastc == '<') {
    239             if (oneXMLchar (lp, '<', errmsg) < 0) {
    240                 initParser(lp);
    241                 return (NULL);
    242             }
    243             /* N.B. we assume '<' will never result in closure */
    244         }
    245 
    246         /* process newc (at last!) */
    247         s = oneXMLchar (lp, newc, errmsg);
    248         if (s == 0) {
    249             lp->lastc = newc;
    250             return (NULL);
    251         }
    252         if (s < 0) {
    253             initParser(lp);
    254             return (NULL);
    255         }
    256 
    257         /* Ok! return ce and we start over.
    258          * N.B. up to caller to call delXMLEle with what we return.
    259          */
    260         root = lp->ce;
    261         lp->ce = NULL;
    262         initParser(lp);
    263         return (root);
     202readXMLEle (LilXML *lp, int newc, char ynot[])
     203{
     204        XMLEle *root;
     205        int s;
     206
     207        /* start optimistic */
     208        ynot[0] = '\0';
     209
     210        /* EOF? */
     211        if (newc == 0) {
     212            sprintf (ynot, "Line %d: early XML EOF", lp->ln);
     213            initParser(lp);
     214            return (NULL);
     215        }
     216
     217        /* new line? */
     218        if (newc == '\n')
     219            lp->ln++;
     220
     221        /* skip comments and declarations. requires 1 char history */
     222        if (!lp->skipping && lp->lastc == '<' && (newc == '?' || newc == '!')) {
     223            lp->skipping = 1;
     224            lp->lastc = newc;
     225            return (NULL);
     226        }
     227        if (lp->skipping) {
     228            if (newc == '>')
     229                lp->skipping = 0;
     230            lp->lastc = newc;
     231            return (NULL);
     232        }
     233        if (newc == '<') {
     234            lp->lastc = '<';
     235            return (NULL);
     236        }
     237
     238        /* do a pending '<' first then newc */
     239        if (lp->lastc == '<') {
     240            if (oneXMLchar (lp, '<', ynot) < 0) {
     241                initParser(lp);
     242                return (NULL);
     243            }
     244            /* N.B. we assume '<' will never result in closure */
     245        }
     246
     247        /* process newc (at last!) */
     248        s = oneXMLchar (lp, newc, ynot);
     249        if (s == 0) {
     250            lp->lastc = newc;
     251            return (NULL);
     252        }
     253        if (s < 0) {
     254            initParser(lp);
     255            return (NULL);
     256        }
     257
     258        /* Ok! return ce and we start over.
     259         * N.B. up to caller to call delXMLEle with what we return.
     260         */
     261        root = lp->ce;
     262        lp->ce = NULL;
     263        initParser(lp);
     264        return (root);
     265}
     266
     267/* parse the given XML string.
     268 * return XMLEle* else NULL with reason why in ynot[]
     269 */
     270XMLEle *
     271parseXML (char buf[], char ynot[])
     272{
     273        LilXML *lp = newLilXML();
     274        XMLEle *root;
     275
     276        do {
     277            root = readXMLEle (lp, *buf++, ynot);
     278        } while (!root && !ynot[0]);
     279
     280        delLilXML (lp);
     281
     282        return (root);
     283}
     284
     285/* return a deep copy of the given XMLEle *
     286 */
     287XMLEle *
     288cloneXMLEle (XMLEle *ep)
     289{
     290        char *buf;
     291        char ynot[1024];
     292        XMLEle *newep;
     293
     294        buf = (*mymalloc) (sprlXMLEle (ep, 0) + 1);
     295        sprXMLEle (buf, ep, 0);
     296        newep = parseXML (buf, ynot);
     297        (*myfree) (buf);
     298
     299        return (newep);
    264300}
    265301
     
    270306findXMLAtt (XMLEle *ep, const char *name)
    271307{
    272         int i;
    273 
    274         for (i = 0; i < ep->nat; i++)
    275             if (!strcmp (ep->at[i]->name.s, name))
    276                 return (ep->at[i]);
    277         return (NULL);
     308        int i;
     309
     310        for (i = 0; i < ep->nat; i++)
     311            if (!strcmp (ep->at[i]->name.s, name))
     312                return (ep->at[i]);
     313        return (NULL);
    278314}
    279315
     
    284320findXMLEle (XMLEle *ep, const char *tag)
    285321{
    286         int tl = strlen (tag);
    287         int i;
    288 
    289         for (i = 0; i < ep->nel; i++) {
    290             String *sp = &ep->el[i]->tag;
    291             if (sp->sl == tl && !strcmp (sp->s, tag))
    292                 return (ep->el[i]);
    293         }
    294         return (NULL);
     322        int tl = strlen (tag);
     323        int i;
     324
     325        for (i = 0; i < ep->nel; i++) {
     326            String *sp = &ep->el[i]->tag;
     327            if (sp->sl == tl && !strcmp (sp->s, tag))
     328                return (ep->el[i]);
     329        }
     330        return (NULL);
    295331}
    296332
     
    302338nextXMLEle (XMLEle *ep, int init)
    303339{
    304         int eit;
    305        
    306         if (init)
    307             ep->eit = 0;
    308 
    309         eit = ep->eit++;
    310         if (eit < 0 || eit >= ep->nel)
    311             return (NULL);
    312         return (ep->el[eit]);
     340        int eit;
     341
     342        if (init)
     343            ep->eit = 0;
     344
     345        eit = ep->eit++;
     346        if (eit < 0 || eit >= ep->nel)
     347            return (NULL);
     348        return (ep->el[eit]);
    313349}
    314350
     
    320356nextXMLAtt (XMLEle *ep, int init)
    321357{
    322         int ait;
    323 
    324         if (init)
    325             ep->ait = 0;
    326 
    327         ait = ep->ait++;
    328         if (ait < 0 || ait >= ep->nat)
    329             return (NULL);
    330         return (ep->at[ait]);
     358        int ait;
     359
     360        if (init)
     361            ep->ait = 0;
     362
     363        ait = ep->ait++;
     364        if (ait < 0 || ait >= ep->nat)
     365            return (NULL);
     366        return (ep->at[ait]);
    331367}
    332368
     
    335371parentXMLEle (XMLEle *ep)
    336372{
    337         return (ep->pe);
     373        return (ep->pe);
    338374}
    339375
     
    342378parentXMLAtt (XMLAtt *ap)
    343379{
    344         return (ap->ce);
     380        return (ap->ce);
    345381}
    346382
     
    351387tagXMLEle (XMLEle *ep)
    352388{
    353         return (ep->tag.s);
     389        return (ep->tag.s);
    354390}
    355391
     
    358394pcdataXMLEle (XMLEle *ep)
    359395{
    360         return (ep->pcdata.s);
     396        return (ep->pcdata.s);
    361397}
    362398
    363399/* return the number of characters in the pcdata portion of the given element */
    364 int 
     400int
    365401pcdatalenXMLEle (XMLEle *ep)
    366402{
    367         return (ep->pcdata.sl);
     403        return (ep->pcdata.sl);
    368404}
    369405
     
    372408nameXMLAtt (XMLAtt *ap)
    373409{
    374         return (ap->name.s);
     410        return (ap->name.s);
    375411}
    376412
     
    379415valuXMLAtt (XMLAtt *ap)
    380416{
    381         return (ap->valu.s);
     417        return (ap->valu.s);
    382418}
    383419
     
    386422nXMLEle (XMLEle *ep)
    387423{
    388         return (ep->nel);
     424        return (ep->nel);
    389425}
    390426
     
    393429nXMLAtt (XMLEle *ep)
    394430{
    395         return (ep->nat);
     431        return (ep->nat);
    396432}
    397433
     
    403439findXMLAttValu (XMLEle *ep, const char *name)
    404440{
    405         XMLAtt *a = findXMLAtt (ep, name);
    406         return (a ? a->valu.s : "");
     441        XMLAtt *a = findXMLAtt (ep, name);
     442        return (a ? a->valu.s : "");
    407443}
    408444
    409445/* handy wrapper to read one xml file.
    410  * return root element else NULL with report in errmsg[]
     446 * return root element else NULL with report in ynot[]
    411447 */
    412448XMLEle *
    413 readXMLFile (FILE *fp, LilXML *lp, char errmsg[])
    414 {
    415         int c;
    416 
    417         while ((c = fgetc(fp)) != EOF) {
    418             XMLEle *root = readXMLEle (lp, c, errmsg);
    419             if (root || errmsg[0])
    420                 return (root);
    421         }
    422 
    423         return (NULL);
     449readXMLFile (FILE *fp, LilXML *lp, char ynot[])
     450{
     451        int c;
     452
     453        while ((c = fgetc(fp)) != EOF) {
     454            XMLEle *root = readXMLEle (lp, c, ynot);
     455            if (root || ynot[0])
     456                return (root);
     457        }
     458
     459        return (NULL);
    424460}
    425461
     
    430466addXMLEle (XMLEle *parent, const char *tag)
    431467{
    432         XMLEle *ep = growEle (parent);
    433         appendString (&ep->tag, tag);
    434         return (ep);
     468        XMLEle *ep = growEle (parent);
     469        appendString (&ep->tag, tag);
     470        return (ep);
     471}
     472
     473/* append an existing element to the given element.
     474 * N.B. be mindful of when these are deleted, this is not a deep copy.
     475 */
     476void
     477appXMLEle (XMLEle *ep, XMLEle *newep)
     478{
     479        ep->el = (XMLEle **) moremem (ep->el, (ep->nel+1)*sizeof(XMLEle *));
     480        ep->el[ep->nel++] = newep;
    435481}
    436482
     
    439485editXMLEle (XMLEle *ep, const char *pcdata)
    440486{
    441         freeString (&ep->pcdata);
    442         appendString (&ep->pcdata, pcdata);
    443         ep->pcdata_hasent = (strpbrk (pcdata, entities) != NULL);
     487        freeString (&ep->pcdata);
     488        appendString (&ep->pcdata, pcdata);
     489        ep->pcdata_hasent = (strpbrk (pcdata, entities) != NULL);
    444490}
    445491
     
    448494addXMLAtt (XMLEle *ep, const char *name, const char *valu)
    449495{
    450         XMLAtt *ap = growAtt (ep);
    451         appendString (&ap->name, name);
    452         appendString (&ap->valu, valu);
    453         return (ap);
     496        XMLAtt *ap = growAtt (ep);
     497        appendString (&ap->name, name);
     498        appendString (&ap->valu, valu);
     499        return (ap);
    454500}
    455501
     
    458504rmXMLAtt (XMLEle *ep, const char *name)
    459505{
    460         int i;
    461 
    462         for (i = 0; i < ep->nat; i++) {
    463             if (strcmp (ep->at[i]->name.s, name) == 0) {
    464                 freeAtt (ep->at[i]);
    465                 memmove (&ep->at[i],&ep->at[i+1],(--ep->nat-i)*sizeof(XMLAtt*));
    466                 return;
    467             }
    468         }
     506        int i;
     507
     508        for (i = 0; i < ep->nat; i++) {
     509            if (strcmp (ep->at[i]->name.s, name) == 0) {
     510                freeAtt (ep->at[i]);
     511                memmove (&ep->at[i],&ep->at[i+1],(--ep->nat-i)*sizeof(XMLAtt*));
     512                return;
     513            }
     514        }
    469515}
    470516
     
    473519editXMLAtt (XMLAtt *ap, const char *str)
    474520{
    475         freeString (&ap->valu);
    476         appendString (&ap->valu, str);
     521        freeString (&ap->valu);
     522        appendString (&ap->valu, str);
    477523}
    478524
     
    484530prXMLEle (FILE *fp, XMLEle *ep, int level)
    485531{
    486         int indent = level*PRINDENT;
    487         int i;
    488 
    489         fprintf (fp, "%*s<%s", indent, "", ep->tag.s);
    490         for (i = 0; i < ep->nat; i++)
    491             fprintf (fp, " %s=\"%s\"", ep->at[i]->name.s,
    492                                                 entityXML(ep->at[i]->valu.s));
    493         if (ep->nel > 0) {
    494             fprintf (fp, ">\n");
    495             for (i = 0; i < ep->nel; i++)
    496                 prXMLEle (fp, ep->el[i], level+1);
    497         }
    498         if (ep->pcdata.sl > 0) {
    499             if (ep->nel == 0)
    500                 fprintf (fp, ">\n");
    501             if (ep->pcdata_hasent)
    502                 fprintf (fp, "%s", entityXML(ep->pcdata.s));
    503             else
    504                 fprintf (fp, "%s", ep->pcdata.s);
    505             if (ep->pcdata.s[ep->pcdata.sl-1] != '\n')
    506                 fprintf (fp, "\n");
    507         }
    508         if (ep->nel > 0 || ep->pcdata.sl > 0)
    509             fprintf (fp, "%*s</%s>\n", indent, "", ep->tag.s);
    510         else
    511             fprintf (fp, "/>\n");
     532        int indent = level*PRINDENT;
     533        int i;
     534
     535        fprintf (fp, "%*s<%s", indent, "", ep->tag.s);
     536        for (i = 0; i < ep->nat; i++)
     537            fprintf (fp, " %s=\"%s\"", ep->at[i]->name.s,
     538                                                entityXML(ep->at[i]->valu.s));
     539        if (ep->nel > 0) {
     540            fprintf (fp, ">\n");
     541            for (i = 0; i < ep->nel; i++)
     542                prXMLEle (fp, ep->el[i], level+1);
     543        }
     544        if (ep->pcdata.sl > 0) {
     545            if (ep->nel == 0)
     546                fprintf (fp, ">\n");
     547            if (ep->pcdata_hasent)
     548                fprintf (fp, "%s", entityXML(ep->pcdata.s));
     549            else
     550                fprintf (fp, "%s", ep->pcdata.s);
     551            if (ep->pcdata.s[ep->pcdata.sl-1] != '\n')
     552                fprintf (fp, "\n");
     553        }
     554        if (ep->nel > 0 || ep->pcdata.sl > 0)
     555            fprintf (fp, "%*s</%s>\n", indent, "", ep->tag.s);
     556        else
     557            fprintf (fp, "/>\n");
    512558}
    513559
     
    520566sprXMLEle (char *s, XMLEle *ep, int level)
    521567{
    522         int indent = level*PRINDENT;
    523         int sl = 0;
    524         int i;
    525 
    526         sl += sprintf (s+sl, "%*s<%s", indent, "", ep->tag.s);
    527         for (i = 0; i < ep->nat; i++)
    528             sl += sprintf (s+sl, " %s=\"%s\"", ep->at[i]->name.s,
    529                                                 entityXML(ep->at[i]->valu.s));
    530         if (ep->nel > 0) {
    531             sl += sprintf (s+sl, ">\n");
    532             for (i = 0; i < ep->nel; i++)
    533                 sl += sprXMLEle (s+sl, ep->el[i], level+1);
    534         }
    535         if (ep->pcdata.sl > 0) {
    536             if (ep->nel == 0)
    537                 sl += sprintf (s+sl, ">\n");
    538             if (ep->pcdata_hasent)
    539                 sl += sprintf (s+sl, "%s", entityXML(ep->pcdata.s));
    540             else {
    541                 strcpy (s+sl, ep->pcdata.s);
    542                 sl += ep->pcdata.sl;
    543             }
    544             if (ep->pcdata.s[ep->pcdata.sl-1] != '\n')
    545                 sl += sprintf (s+sl, "\n");
    546         }
    547         if (ep->nel > 0 || ep->pcdata.sl > 0)
    548             sl += sprintf (s+sl, "%*s</%s>\n", indent, "", ep->tag.s);
    549         else
    550             sl += sprintf (s+sl, "/>\n");
    551 
    552         return (sl);
     568        int indent = level*PRINDENT;
     569        int sl = 0;
     570        int i;
     571
     572        sl += sprintf (s+sl, "%*s<%s", indent, "", ep->tag.s);
     573        for (i = 0; i < ep->nat; i++)
     574            sl += sprintf (s+sl, " %s=\"%s\"", ep->at[i]->name.s,
     575                                                entityXML(ep->at[i]->valu.s));
     576        if (ep->nel > 0) {
     577            sl += sprintf (s+sl, ">\n");
     578            for (i = 0; i < ep->nel; i++)
     579                sl += sprXMLEle (s+sl, ep->el[i], level+1);
     580        }
     581        if (ep->pcdata.sl > 0) {
     582            if (ep->nel == 0)
     583                sl += sprintf (s+sl, ">\n");
     584            if (ep->pcdata_hasent)
     585                sl += sprintf (s+sl, "%s", entityXML(ep->pcdata.s));
     586            else {
     587                strcpy (s+sl, ep->pcdata.s);
     588                sl += ep->pcdata.sl;
     589            }
     590            if (ep->pcdata.s[ep->pcdata.sl-1] != '\n')
     591                sl += sprintf (s+sl, "\n");
     592        }
     593        if (ep->nel > 0 || ep->pcdata.sl > 0)
     594            sl += sprintf (s+sl, "%*s</%s>\n", indent, "", ep->tag.s);
     595        else
     596            sl += sprintf (s+sl, "/>\n");
     597
     598        return (sl);
    553599}
    554600
     
    560606sprlXMLEle (XMLEle *ep, int level)
    561607{
    562         int indent = level*PRINDENT;
    563         int l = 0;
    564         int i;
    565 
    566         l += indent + 1 + ep->tag.sl;
    567         for (i = 0; i < ep->nat; i++)
    568             l += ep->at[i]->name.sl + 4 + strlen(entityXML(ep->at[i]->valu.s));
    569 
    570         if (ep->nel > 0) {
    571             l += 2;
    572             for (i = 0; i < ep->nel; i++)
    573                 l += sprlXMLEle (ep->el[i], level+1);
    574         }
    575         if (ep->pcdata.sl > 0) {
    576             if (ep->nel == 0)
    577                 l += 2;
    578             if (ep->pcdata_hasent)
    579                 l += strlen (entityXML(ep->pcdata.s));
    580             else
    581                 l += ep->pcdata.sl;
    582             if (ep->pcdata.s[ep->pcdata.sl-1] != '\n')
    583                 l += 1;
    584         }
    585         if (ep->nel > 0 || ep->pcdata.sl > 0)
    586             l += indent + 4 + ep->tag.sl;
    587         else
    588             l += 3;
    589 
    590         return (l);
     608        int indent = level*PRINDENT;
     609        int l = 0;
     610        int i;
     611
     612        l += indent + 1 + ep->tag.sl;
     613        for (i = 0; i < ep->nat; i++)
     614            l += ep->at[i]->name.sl + 4 + strlen(entityXML(ep->at[i]->valu.s));
     615
     616        if (ep->nel > 0) {
     617            l += 2;
     618            for (i = 0; i < ep->nel; i++)
     619                l += sprlXMLEle (ep->el[i], level+1);
     620        }
     621        if (ep->pcdata.sl > 0) {
     622            if (ep->nel == 0)
     623                l += 2;
     624            if (ep->pcdata_hasent)
     625                l += strlen (entityXML(ep->pcdata.s));
     626            else
     627                l += ep->pcdata.sl;
     628            if (ep->pcdata.s[ep->pcdata.sl-1] != '\n')
     629                l += 1;
     630        }
     631        if (ep->nel > 0 || ep->pcdata.sl > 0)
     632            l += indent + 4 + ep->tag.sl;
     633        else
     634            l += 3;
     635
     636        return (l);
    591637}
    592638
     
    598644entityXML (char *s)
    599645{
    600         static char *malbuf;
    601         int nmalbuf = 0;
    602         char *sret;
    603         char *ep;
    604 
    605         /* scan for each entity, if any */
    606         for (sret = s; (ep = strpbrk (s, entities)) != NULL; s = ep+1) {
    607 
    608             /* found another entity, copy preceding to malloced buffer */
    609             int nnew = ep - s;                  /* all but entity itself */
    610             sret = malbuf = moremem (malbuf, nmalbuf + nnew + 10);
    611             memcpy (malbuf+nmalbuf, s, nnew);
    612             nmalbuf += nnew;
    613 
    614             /* replace with entity encoding */
    615             switch (*ep) {
    616             case '&':
    617                 nmalbuf += sprintf (malbuf+nmalbuf, "&amp;");
    618                 break;
    619             case '<':
    620                 nmalbuf += sprintf (malbuf+nmalbuf, "&lt;");
    621                 break;
    622             case '>':
    623                 nmalbuf += sprintf (malbuf+nmalbuf, "&gt;");
    624                 break;
    625             case '\'':
    626                 nmalbuf += sprintf (malbuf+nmalbuf, "&apos;");
    627                 break;
    628             case '"':
    629                 nmalbuf += sprintf (malbuf+nmalbuf, "&quot;");
    630                 break;
    631 
    632             }
    633 
    634         }
    635 
    636         /* return s if no entities, else malloc cleaned-up copy */
    637         if (sret == s) {
    638             /* using s, so free any malloced memory from last time */
    639             if (malbuf) {
    640                 free (malbuf);
    641                 malbuf = NULL;
    642             }
    643         } else {
    644             /* put remaining part of s into malbuf */
    645             int nleft = strlen (s) + 1;         /* include \0 */
    646             sret = malbuf = moremem (malbuf, nmalbuf + nleft);
    647             memcpy (malbuf+nmalbuf, s, nleft);
    648         }
    649 
    650         return (sret);
    651 }
     646        static char *malbuf;
     647        int nmalbuf = 0;
     648        char *sret;
     649        char *ep;
     650
     651        /* scan for each entity, if any */
     652        for (sret = s; (ep = strpbrk (s, entities)) != NULL; s = ep+1) {
     653
     654            /* found another entity, copy preceding to malloced buffer */
     655            int nnew = ep - s;                  /* all but entity itself */
     656            sret = malbuf = moremem (malbuf, nmalbuf + nnew + 10);
     657            memcpy (malbuf+nmalbuf, s, nnew);
     658            nmalbuf += nnew;
     659
     660            /* replace with entity encoding */
     661            switch (*ep) {
     662            case '&':
     663                nmalbuf += sprintf (malbuf+nmalbuf, "&amp;");
     664                break;
     665            case '<':
     666                nmalbuf += sprintf (malbuf+nmalbuf, "&lt;");
     667                break;
     668            case '>':
     669                nmalbuf += sprintf (malbuf+nmalbuf, "&gt;");
     670                break;
     671            case '\'':
     672                nmalbuf += sprintf (malbuf+nmalbuf, "&apos;");
     673                break;
     674            case '"':
     675                nmalbuf += sprintf (malbuf+nmalbuf, "&quot;");
     676                break;
     677
     678            }
     679
     680        }
     681
     682        /* return s if no entities, else malloc cleaned-up copy */
     683        if (sret == s) {
     684            /* using s, so free any malloced memory from last time */
     685            if (malbuf) {
     686                free (malbuf);
     687                malbuf = NULL;
     688            }
     689        } else {
     690            /* put remaining part of s into malbuf */
     691            int nleft = strlen (s) + 1;         /* include \0 */
     692            sret = malbuf = moremem (malbuf, nmalbuf + nleft);
     693            memcpy (malbuf+nmalbuf, s, nleft);
     694        }
     695
     696        return (sret);
     697}
     698
     699
     700
    652701
    653702/* if ent is a recognized xml entity sequence, set *cp to char and return 1
     
    657706decodeEntity (char *ent, int *cp)
    658707{
    659         static struct {
    660             const char *ent;
    661             char c;
    662         } enttable[] = {
    663             {"&amp;",  '&'},
    664             {"&apos;", '\''},
    665             {"&lt;",   '<'},
    666             {"&gt;",   '>'},
    667             {"&quot;", '"'},
    668         };
    669         unsigned int i;
    670 
    671         for (i = 0; i < sizeof(enttable)/sizeof(enttable[0]); i++) {
    672             if (strcmp (ent, enttable[i].ent) == 0) {
    673                 *cp = enttable[i].c;
    674                 return (1);
    675             }
    676         }
    677        
    678         return (0);
     708        static struct {
     709            char *ent;
     710            char c;
     711        } enttable[] = {
     712            {"&amp;",  '&'},
     713            {"&apos;", '\''},
     714            {"&lt;",   '<'},
     715            {"&gt;",   '>'},
     716            {"&quot;", '"'},
     717        };
     718        int i;
     719
     720        for (i = 0; i < sizeof(enttable)/sizeof(enttable[0]); i++) {
     721            if (strcmp (ent, enttable[i].ent) == 0) {
     722                *cp = enttable[i].c;
     723                return (1);
     724            }
     725        }
     726
     727        return (0);
    679728}
    680729
     
    682731 * if find final closure, return 1 and tree is in ce.
    683732 * if need more, return 0.
    684  * if real trouble, return -1 and put reason in errmsg.
     733 * if real trouble, return -1 and put reason in ynot.
    685734 */
    686735static int
    687 oneXMLchar (LilXML *lp, int c, char errmsg[])
    688 {
    689         switch (lp->cs) {
    690         case LOOK4START:                /* looking for first element start */
    691             if (c == '<') {
    692                 pushXMLEle(lp);
    693                 lp->cs = LOOK4TAG;
    694             }
    695             /* silently ignore until resync */
    696             break;
    697 
    698         case LOOK4TAG:                  /* looking for element tag */
    699             if (isTokenChar (1, c)) {
    700                 growString (&lp->ce->tag, c);
    701                 lp->cs = INTAG;
    702             } else if (!isspace(c)) {
    703                 sprintf (errmsg, "Line %d: Bogus tag char %c", lp->ln, c);
    704                 return (-1);
    705             }
    706             break;
    707                
    708         case INTAG:                     /* reading tag */
    709             if (isTokenChar (0, c))
    710                 growString (&lp->ce->tag, c);
    711             else if (c == '>')
    712                 lp->cs = LOOK4CON;
    713             else if (c == '/')
    714                 lp->cs = SAWSLASH;
    715             else
    716                 lp->cs = LOOK4ATTRN;
    717             break;
    718 
    719         case LOOK4ATTRN:                /* looking for attr name, > or / */
    720             if (c == '>')
    721                 lp->cs = LOOK4CON;
    722             else if (c == '/')
    723                 lp->cs = SAWSLASH;
    724             else if (isTokenChar (1, c)) {
    725                 XMLAtt *ap = growAtt(lp->ce);
    726                 growString (&ap->name, c);
    727                 lp->cs = INATTRN;
    728             } else if (!isspace(c)) {
    729                 sprintf (errmsg, "Line %d: Bogus leading attr name char: %c",
    730                                                                     lp->ln, c);
    731                 return (-1);
    732             }
    733             break;
    734 
    735         case SAWSLASH:                  /* saw / in element opening */
    736             if (c == '>') {
    737                 if (!lp->ce->pe)
    738                     return(1);          /* root has no content */
    739                 popXMLEle(lp);
    740                 lp->cs = LOOK4CON;
    741             } else {
    742                 sprintf (errmsg, "Line %d: Bogus char %c before >", lp->ln, c);
    743                 return (-1);
    744             }
    745             break;
    746                
    747         case INATTRN:                   /* reading attr name */
    748             if (isTokenChar (0, c))
    749                 growString (&lp->ce->at[lp->ce->nat-1]->name, c);
    750             else if (isspace(c) || c == '=')
    751                 lp->cs = LOOK4ATTRV;
    752             else {
    753                 sprintf (errmsg, "Line %d: Bogus attr name char: %c", lp->ln,c);
    754                 return (-1);
    755             }
    756             break;
    757 
    758         case LOOK4ATTRV:                /* looking for attr value */
    759             if (c == '\'' || c == '"') {
    760                 lp->delim = c;
    761                 lp->cs = INATTRV;
    762             } else if (!(isspace(c) || c == '=')) {
    763                 sprintf (errmsg, "Line %d: No value for attribute %s", lp->ln,
    764                                         lp->ce->at[lp->ce->nat-1]->name.s);
    765                 return (-1);
    766             }
    767             break;
    768 
    769         case INATTRV:                   /* in attr value */
    770             if (c == '&') {
    771                 newString (&lp->entity);
    772                 growString (&lp->entity, c);
    773                 lp->cs = ENTINATTRV;
    774             } else if (c == lp->delim)
    775                 lp->cs = LOOK4ATTRN;
    776             else if (!iscntrl(c))
    777                 growString (&lp->ce->at[lp->ce->nat-1]->valu, c);
    778             break;
    779 
    780         case ENTINATTRV:                /* working on entity in attr valu */
    781             if (c == ';') {
    782                 /* if find a recongized esp seq, add equiv char else raw seq */
    783                 growString (&lp->entity, c);
    784                 if (decodeEntity (lp->entity.s, &c))
    785                     growString (&lp->ce->at[lp->ce->nat-1]->valu, c);
    786                 else
    787                     appendString(&lp->ce->at[lp->ce->nat-1]->valu,lp->entity.s);
    788                 freeString (&lp->entity);
    789                 lp->cs = INATTRV;
    790             } else
    791                 growString (&lp->entity, c);
    792             break;
    793 
    794         case LOOK4CON:                  /* skipping leading content whitespace*/
    795             if (c == '<')
    796                 lp->cs = SAWLTINCON;
    797             else if (!isspace(c)) {
    798                 growString (&lp->ce->pcdata, c);
    799                 lp->cs = INCON;
    800             }
    801             break;
    802 
    803         case INCON:                     /* reading content */
    804             if (c == '&') {
    805                 newString (&lp->entity);
    806                 growString (&lp->entity, c);
    807                 lp->cs = ENTINCON;
    808             } else if (c == '<') {
    809                 /* chomp trailing whitespace */
    810                 while (lp->ce->pcdata.sl > 0 &&
    811                             isspace(lp->ce->pcdata.s[lp->ce->pcdata.sl-1]))
    812                     lp->ce->pcdata.s[--(lp->ce->pcdata.sl)] = '\0';
    813                 lp->cs = SAWLTINCON;
    814             } else {
    815                 growString (&lp->ce->pcdata, c);
    816             }
    817             break;
    818 
    819         case ENTINCON:                  /* working on entity in content */
    820             if (c == ';') {
    821                 /* if find a recognized esc seq, add equiv char else raw seq */
    822                 growString (&lp->entity, c);
    823                 if (decodeEntity (lp->entity.s, &c))
    824                     growString (&lp->ce->pcdata, c);
    825                 else {
    826                     appendString(&lp->ce->pcdata, lp->entity.s);
    827                     lp->ce->pcdata_hasent = 1;
    828                 }
    829                 freeString (&lp->entity);
    830                 lp->cs = INCON;
    831             } else
    832                 growString (&lp->entity, c);
    833             break;
    834 
    835         case SAWLTINCON:                /* saw < in content */
    836             if (c == '/') {
    837                 resetEndTag(lp);
    838                 lp->cs = LOOK4CLOSETAG;
    839             } else {
    840                 pushXMLEle(lp);
    841                 if (isTokenChar(1,c)) {
    842                     growString (&lp->ce->tag, c);
    843                     lp->cs = INTAG;
    844                 } else
    845                     lp->cs = LOOK4TAG;
    846             }
    847             break;
    848 
    849         case LOOK4CLOSETAG:             /* looking for closing tag after < */
    850             if (isTokenChar (1, c)) {
    851                 growString (&lp->endtag, c);
    852                 lp->cs = INCLOSETAG;
    853             } else if (!isspace(c)) {
    854                 sprintf (errmsg, "Line %d: Bogus preend tag char %c", lp->ln,c);
    855                 return (-1);
    856             }
    857             break;
    858 
    859         case INCLOSETAG:                /* reading closing tag */
    860             if (isTokenChar(0, c))
    861                 growString (&lp->endtag, c);
    862             else if (c == '>') {
    863                 if (strcmp (lp->ce->tag.s, lp->endtag.s)) {
    864                     sprintf (errmsg,"Line %d: closing tag %s does not match %s",
    865                                     lp->ln, lp->endtag.s, lp->ce->tag.s);
    866                     return (-1);
    867                 } else if (lp->ce->pe) {
    868                     popXMLEle(lp);
    869                     lp->cs = LOOK4CON;  /* back to content after nested elem */
    870                 } else
    871                     return (1);         /* yes! */
    872             } else if (!isspace(c)) {
    873                 sprintf (errmsg, "Line %d: Bogus end tag char %c", lp->ln, c);
    874                 return (-1);
    875             }
    876             break;
    877         }
    878 
    879         return (0);
     736oneXMLchar (LilXML *lp, int c, char ynot[])
     737{
     738        switch (lp->cs) {
     739        case LOOK4START:                /* looking for first element start */
     740            if (c == '<') {
     741                pushXMLEle(lp);
     742                lp->cs = LOOK4TAG;
     743            }
     744            /* silently ignore until resync */
     745            break;
     746
     747        case LOOK4TAG:                  /* looking for element tag */
     748            if (isTokenChar (1, c)) {
     749                growString (&lp->ce->tag, c);
     750                lp->cs = INTAG;
     751            } else if (!isspace(c)) {
     752                sprintf (ynot, "Line %d: Bogus tag char %c", lp->ln, c);
     753                return (-1);
     754            }
     755            break;
     756
     757        case INTAG:                     /* reading tag */
     758            if (isTokenChar (0, c))
     759                growString (&lp->ce->tag, c);
     760            else if (c == '>')
     761                lp->cs = LOOK4CON;
     762            else if (c == '/')
     763                lp->cs = SAWSLASH;
     764            else
     765                lp->cs = LOOK4ATTRN;
     766            break;
     767
     768        case LOOK4ATTRN:                /* looking for attr name, > or / */
     769            if (c == '>')
     770                lp->cs = LOOK4CON;
     771            else if (c == '/')
     772                lp->cs = SAWSLASH;
     773            else if (isTokenChar (1, c)) {
     774                XMLAtt *ap = growAtt(lp->ce);
     775                growString (&ap->name, c);
     776                lp->cs = INATTRN;
     777            } else if (!isspace(c)) {
     778                sprintf (ynot, "Line %d: Bogus leading attr name char: %c",
     779                                                                    lp->ln, c);
     780                return (-1);
     781            }
     782            break;
     783
     784        case SAWSLASH:                  /* saw / in element opening */
     785            if (c == '>') {
     786                if (!lp->ce->pe)
     787                    return(1);          /* root has no content */
     788                popXMLEle(lp);
     789                lp->cs = LOOK4CON;
     790            } else {
     791                sprintf (ynot, "Line %d: Bogus char %c before >", lp->ln, c);
     792                return (-1);
     793            }
     794            break;
     795
     796        case INATTRN:                   /* reading attr name */
     797            if (isTokenChar (0, c))
     798                growString (&lp->ce->at[lp->ce->nat-1]->name, c);
     799            else if (isspace(c) || c == '=')
     800                lp->cs = LOOK4ATTRV;
     801            else {
     802                sprintf (ynot, "Line %d: Bogus attr name char: %c", lp->ln,c);
     803                return (-1);
     804            }
     805            break;
     806
     807        case LOOK4ATTRV:                /* looking for attr value */
     808            if (c == '\'' || c == '"') {
     809                lp->delim = c;
     810                lp->cs = INATTRV;
     811            } else if (!(isspace(c) || c == '=')) {
     812                sprintf (ynot, "Line %d: No value for attribute %s", lp->ln,
     813                                        lp->ce->at[lp->ce->nat-1]->name.s);
     814                return (-1);
     815            }
     816            break;
     817
     818        case INATTRV:                   /* in attr value */
     819            if (c == '&') {
     820                newString (&lp->entity);
     821                growString (&lp->entity, c);
     822                lp->cs = ENTINATTRV;
     823            } else if (c == lp->delim)
     824                lp->cs = LOOK4ATTRN;
     825            else if (!iscntrl(c))
     826                growString (&lp->ce->at[lp->ce->nat-1]->valu, c);
     827            break;
     828
     829        case ENTINATTRV:                /* working on entity in attr valu */
     830            if (c == ';') {
     831                /* if find a recongized esp seq, add equiv char else raw seq */
     832                growString (&lp->entity, c);
     833                if (decodeEntity (lp->entity.s, &c))
     834                    growString (&lp->ce->at[lp->ce->nat-1]->valu, c);
     835                else
     836                    appendString(&lp->ce->at[lp->ce->nat-1]->valu,lp->entity.s);
     837                freeString (&lp->entity);
     838                lp->cs = INATTRV;
     839            } else
     840                growString (&lp->entity, c);
     841            break;
     842
     843        case LOOK4CON:                  /* skipping leading content whitespace*/
     844            if (c == '<')
     845                lp->cs = SAWLTINCON;
     846            else if (!isspace(c)) {
     847                growString (&lp->ce->pcdata, c);
     848                lp->cs = INCON;
     849            }
     850            break;
     851
     852        case INCON:                     /* reading content */
     853            if (c == '&') {
     854                newString (&lp->entity);
     855                growString (&lp->entity, c);
     856                lp->cs = ENTINCON;
     857            } else if (c == '<') {
     858                /* chomp trailing whitespace */
     859                while (lp->ce->pcdata.sl > 0 &&
     860                            isspace(lp->ce->pcdata.s[lp->ce->pcdata.sl-1]))
     861                    lp->ce->pcdata.s[--(lp->ce->pcdata.sl)] = '\0';
     862                lp->cs = SAWLTINCON;
     863            } else {
     864                growString (&lp->ce->pcdata, c);
     865            }
     866            break;
     867
     868        case ENTINCON:                  /* working on entity in content */
     869            if (c == ';') {
     870                /* if find a recognized esc seq, add equiv char else raw seq */
     871                growString (&lp->entity, c);
     872                if (decodeEntity (lp->entity.s, &c))
     873                    growString (&lp->ce->pcdata, c);
     874                else {
     875                    appendString(&lp->ce->pcdata, lp->entity.s);
     876                    lp->ce->pcdata_hasent = 1;
     877                }
     878                freeString (&lp->entity);
     879                lp->cs = INCON;
     880            } else
     881                growString (&lp->entity, c);
     882            break;
     883
     884        case SAWLTINCON:                /* saw < in content */
     885            if (c == '/') {
     886                resetEndTag(lp);
     887                lp->cs = LOOK4CLOSETAG;
     888            } else {
     889                pushXMLEle(lp);
     890                if (isTokenChar(1,c)) {
     891                    growString (&lp->ce->tag, c);
     892                    lp->cs = INTAG;
     893                } else
     894                    lp->cs = LOOK4TAG;
     895            }
     896            break;
     897
     898        case LOOK4CLOSETAG:             /* looking for closing tag after < */
     899            if (isTokenChar (1, c)) {
     900                growString (&lp->endtag, c);
     901                lp->cs = INCLOSETAG;
     902            } else if (!isspace(c)) {
     903                sprintf (ynot, "Line %d: Bogus preend tag char %c", lp->ln,c);
     904                return (-1);
     905            }
     906            break;
     907
     908        case INCLOSETAG:                /* reading closing tag */
     909            if (isTokenChar(0, c))
     910                growString (&lp->endtag, c);
     911            else if (c == '>') {
     912                if (strcmp (lp->ce->tag.s, lp->endtag.s)) {
     913                    sprintf (ynot,"Line %d: closing tag %s does not match %s",
     914                                    lp->ln, lp->endtag.s, lp->ce->tag.s);
     915                    return (-1);
     916                } else if (lp->ce->pe) {
     917                    popXMLEle(lp);
     918                    lp->cs = LOOK4CON;  /* back to content after nested elem */
     919                } else
     920                    return (1);         /* yes! */
     921            } else if (!isspace(c)) {
     922                sprintf (ynot, "Line %d: Bogus end tag char %c", lp->ln, c);
     923                return (-1);
     924            }
     925            break;
     926        }
     927
     928        return (0);
    880929}
    881930
     
    884933initParser(LilXML *lp)
    885934{
    886         delXMLEle (lp->ce);
    887         freeString (&lp->endtag);
    888         memset (lp, 0, sizeof(*lp));
    889         newString (&lp->endtag);
    890         lp->cs = LOOK4START;
    891         lp->ln = 1;
     935        delXMLEle (lp->ce);
     936        freeString (&lp->endtag);
     937        memset (lp, 0, sizeof(*lp));
     938        newString (&lp->endtag);
     939        lp->cs = LOOK4START;
     940        lp->ln = 1;
    892941}
    893942
     
    900949pushXMLEle(LilXML *lp)
    901950{
    902         lp->ce = growEle (lp->ce);
    903         resetEndTag(lp);
     951        lp->ce = growEle (lp->ce);
     952        resetEndTag(lp);
    904953}
    905954
     
    910959popXMLEle(LilXML *lp)
    911960{
    912         lp->ce = lp->ce->pe;
    913         resetEndTag(lp);
     961        lp->ce = lp->ce->pe;
     962        resetEndTag(lp);
    914963}
    915964
     
    918967growEle (XMLEle *pe)
    919968{
    920         XMLEle *newe = (XMLEle *) moremem (NULL, sizeof(XMLEle));
    921 
    922         memset (newe, 0, sizeof(XMLEle));
    923         newString (&newe->tag);
    924         newString (&newe->pcdata);
    925         newe->pe = pe;
    926 
    927         if (pe) {
    928             pe->el = (XMLEle **) moremem (pe->el, (pe->nel+1)*sizeof(XMLEle *));
    929             pe->el[pe->nel++] = newe;
    930         }
    931 
    932         return (newe);
     969        XMLEle *newe = (XMLEle *) moremem (NULL, sizeof(XMLEle));
     970
     971        memset (newe, 0, sizeof(XMLEle));
     972        newString (&newe->tag);
     973        newString (&newe->pcdata);
     974        newe->pe = pe;
     975
     976        if (pe) {
     977            pe->el = (XMLEle **) moremem (pe->el, (pe->nel+1)*sizeof(XMLEle *));
     978            pe->el[pe->nel++] = newe;
     979        }
     980
     981        return (newe);
    933982}
    934983
     
    937986growAtt(XMLEle *ep)
    938987{
    939         XMLAtt *newa = (XMLAtt *) moremem (NULL, sizeof(XMLAtt));
    940 
    941         memset (newa, 0, sizeof(*newa));
    942         newString(&newa->name);
    943         newString(&newa->valu);
    944         newa->ce = ep;
    945 
    946         ep->at = (XMLAtt **) moremem (ep->at, (ep->nat+1)*sizeof(XMLAtt *));
    947         ep->at[ep->nat++] = newa;
    948 
    949         return (newa);
     988        XMLAtt *newa = (XMLAtt *) moremem (NULL, sizeof(XMLAtt));
     989
     990        memset (newa, 0, sizeof(*newa));
     991        newString(&newa->name);
     992        newString(&newa->valu);
     993        newa->ce = ep;
     994
     995        ep->at = (XMLAtt **) moremem (ep->at, (ep->nat+1)*sizeof(XMLAtt *));
     996        ep->at[ep->nat++] = newa;
     997
     998        return (newa);
    950999}
    9511000
     
    9541003freeAtt (XMLAtt *a)
    9551004{
    956         if (!a)
    957             return;
    958         freeString (&a->name);
    959         freeString (&a->valu);
    960         (*myfree)(a);
     1005        if (!a)
     1006            return;
     1007        freeString (&a->name);
     1008        freeString (&a->valu);
     1009        (*myfree)(a);
    9611010}
    9621011
     
    9651014resetEndTag(LilXML *lp)
    9661015{
    967         freeString (&lp->endtag);
    968         newString (&lp->endtag);
     1016        freeString (&lp->endtag);
     1017        newString (&lp->endtag);
    9691018}
    9701019
     
    9751024isTokenChar (int start, int c)
    9761025{
    977         return (isalpha(c) || c == '_' || (!start && isdigit(c)));
     1026        return (isalpha(c) || c == '_' || (!start && isdigit(c)));
    9781027}
    9791028
     
    9821031growString (String *sp, int c)
    9831032{
    984         int l = sp->sl + 2;             /* need room for '\0' plus c */
    985 
    986         if (l > sp->sm) {
    987             if (!sp->s)
    988                 newString (sp);
    989             else
    990                 sp->s = (char *) moremem (sp->s, sp->sm *= 2);
    991         }
    992         sp->s[--l] = '\0';
    993         sp->s[--l] = (char)c;
    994         sp->sl++;
     1033        int l = sp->sl + 2;             /* need room for '\0' plus c */
     1034
     1035        if (l > sp->sm) {
     1036            if (!sp->s)
     1037                newString (sp);
     1038            else
     1039                sp->s = (char *) moremem (sp->s, sp->sm *= 2);
     1040        }
     1041        sp->s[--l] = '\0';
     1042        sp->s[--l] = (char)c;
     1043        sp->sl++;
    9951044}
    9961045
     
    9991048appendString (String *sp, const char *str)
    10001049{
    1001         int strl = strlen (str);
    1002         int l = sp->sl + strl + 1;      /* need room for '\0' */
    1003 
    1004         if (l > sp->sm) {
    1005             if (!sp->s)
    1006                 newString (sp);
    1007             if (l > sp->sm)
    1008                 sp->s = (char *) moremem (sp->s, (sp->sm = l));
    1009         }
    1010         strcpy (&sp->s[sp->sl], str);
    1011         sp->sl += strl;         
     1050        int strl = strlen (str);
     1051        int l = sp->sl + strl + 1;      /* need room for '\0' */
     1052
     1053        if (l > sp->sm) {
     1054            if (!sp->s)
     1055                newString (sp);
     1056            if (l > sp->sm)
     1057                sp->s = (char *) moremem (sp->s, (sp->sm = l));
     1058        }
     1059        strcpy (&sp->s[sp->sl], str);
     1060        sp->sl += strl;
    10121061}
    10131062
     
    10161065newString(String *sp)
    10171066{
    1018         sp->s = (char *)moremem(NULL, MINMEM);
    1019         sp->sm = MINMEM;
    1020         *sp->s = '\0';
    1021         sp->sl = 0;
     1067        sp->s = (char *)moremem(NULL, MINMEM);
     1068        sp->sm = MINMEM;
     1069        *sp->s = '\0';
     1070        sp->sl = 0;
    10221071}
    10231072
     
    10261075freeString (String *sp)
    10271076{
    1028         if (sp->s)
    1029             (*myfree) (sp->s);
    1030         sp->s = NULL;
    1031         sp->sl = 0;
    1032         sp->sm = 0;
     1077        if (sp->s)
     1078            (*myfree) (sp->s);
     1079        sp->s = NULL;
     1080        sp->sl = 0;
     1081        sp->sm = 0;
    10331082}
    10341083
     
    10371086moremem (void *old, int n)
    10381087{
    1039         return (old ? (*myrealloc)(old, n) : (*mymalloc)(n));
     1088        return (old ? (*myrealloc)(old, n) : (*mymalloc)(n));
    10401089}
    10411090
     
    10441093main (int ac, char *av[])
    10451094{
    1046         LilXML *lp = newLilXML();
    1047         char errmsg[1024];
    1048         XMLEle *root;
    1049 
    1050         root = readXMLFile (stdin, lp, errmsg);
    1051         if (root) {
    1052             char *str;
    1053             int l;
    1054 
    1055             if (ac > 1) {
    1056                 XMLEle *theend = addXMLEle (root, "theend");
    1057                 editXMLEle (theend, "Added to test editing");
    1058                 addXMLAtt (theend, "hello", "world");
    1059             }
    1060 
    1061             fprintf (stderr, "::::::::::::: %s\n", tagXMLEle(root));
    1062             prXMLEle (stdout, root, 0);
    1063 
    1064             l = sprlXMLEle (root, 0);
    1065             str = malloc (l+1);
    1066             fprintf (stderr, "::::::::::::: %s : %d : %d",
    1067                                 tagXMLEle(root), l, sprXMLEle (str, root, 0));
    1068             fprintf (stderr, ": %d\n", printf ("%s", str));
    1069 
    1070             delXMLEle (root);
    1071         } else if (errmsg[0]) {
    1072             fprintf (stderr, "Error: %s\n", errmsg);
    1073         }
    1074 
    1075         delLilXML (lp);
    1076 
    1077         return (0);
     1095        LilXML *lp = newLilXML();
     1096        char ynot[1024];
     1097        XMLEle *root;
     1098
     1099        root = readXMLFile (stdin, lp, ynot);
     1100        if (root) {
     1101            char *str;
     1102            int l;
     1103
     1104            if (ac > 1) {
     1105                XMLEle *theend = addXMLEle (root, "theend");
     1106                editXMLEle (theend, "Added to test editing");
     1107                addXMLAtt (theend, "hello", "world");
     1108            }
     1109
     1110            fprintf (stderr, "::::::::::::: %s\n", tagXMLEle(root));
     1111            prXMLEle (stdout, root, 0);
     1112
     1113            l = sprlXMLEle (root, 0);
     1114            str = malloc (l+1);
     1115            fprintf (stderr, "::::::::::::: %s : %d : %d",
     1116                                tagXMLEle(root), l, sprXMLEle (str, root, 0));
     1117            fprintf (stderr, ": %d\n", printf ("%s", str));
     1118
     1119            delXMLEle (root);
     1120        } else if (ynot[0]) {
     1121            fprintf (stderr, "Error: %s\n", ynot);
     1122        }
     1123
     1124        delLilXML (lp);
     1125
     1126        return (0);
    10781127}
    10791128#endif
    1080 
  • BAORadio/libindi/libindi/libs/webcam/port.cpp

    r490 r642  
    3838#include <sys/stat.h>
    3939#endif /* LOCKING */
    40 
    4140#ifdef __linux__
    42   #if defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) || defined(__powerpc__) || defined(__s390__) || defined(__s390x__) || defined(__mips__) || defined(__mc68000__)
     41#if defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) \
     42        || defined(__powerpc__) || defined(__s390__) || defined(__s390x__)\
     43        || defined(__mips__) || defined(__mc68000__) || defined(__sh__)
     44#define NO_SYSIO
     45#endif /* architechtures */
     46#endif /* __linux__ */
     47
     48#ifdef __linux__
     49  #if defined(NO_SYSIO)
    4350  #include <fcntl.h>
    4451  #else
    4552  #include <sys/io.h>
    46   #endif /* arm */
     53  #endif /* NO_SYSIO */
    4754#elif defined(QNX)
    4855#include <conio.h>
     
    7784
    7885#ifdef LINUX
    79 #if defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) || defined(__powerpc__) || defined(__s390__) || defined(__s390x__) || defined(__mips__) || defined(__mc68000__)
     86#ifdef NO_SYSIO
    8087  if ((devport = open("/dev/port", O_RDWR)) < 0) {
    8188    perror("open /dev/port");
     
    8794    return;
    8895  }
    89 #endif /* arm */
     96#endif /* NO_SYSIO */
    9097#elif defined(FREEBSD)
    9198  if ((devio = fopen("/dev/io", "r+")) == NULL) {
     
    121128#endif /* LOCKING */
    122129#ifdef LINUX
    123 #if defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) || defined(__powerpc__) || defined(__s390__) || defined(__s390x__) || defined(__mips__) || defined(__mc68000__)
     130#ifdef NO_SYSIO
    124131  if (devport >= 0)
    125132    close(devport);
     
    129136                                  // be root
    130137      perror("ioperm()");
    131 #endif /* arm */
     138#endif /* NO_SYSIO */
    132139#elif defined(FREEBSD)
    133140  if (devio != NULL)
  • BAORadio/libindi/libindi/tools/compiler.c

    r490 r642  
    267267next_token ()
    268268{
    269         static char toomv[] = "More than %d variables";
    270         static char toomc[] = "More than %d constants";
    271         static char badop[] = "Illegal operator";
     269        static const char toomv[] = "More than %d variables";
     270        static const char toomc[] = "More than %d constants";
     271        static const char badop[] = "Illegal operator";
    272272        int tok = ERR;  /* just something illegal */
    273273        char c;
     
    295295        case '|':
    296296            if (*cexpr == '|') { cexpr++; tok = OR; }
    297             else { (void) sprintf (err_msg, badop); return (ERR); }
     297            else { (void) strcpy (err_msg, badop); return (ERR); }
    298298            break;
    299299        case '&':
    300300            if (*cexpr == '&') { cexpr++; tok = AND; }
    301             else { (void) sprintf (err_msg, badop); return (ERR); }
     301            else { (void) strcpy (err_msg, badop); return (ERR); }
    302302            break;
    303303        case '=':
    304304            if (*cexpr == '=') { cexpr++; tok = EQ; }
    305             else { (void) sprintf (err_msg, badop); return (ERR); }
     305            else { (void) strcpy (err_msg, badop); return (ERR); }
    306306            break;
    307307        case '!':
  • BAORadio/libindi/libindi/tools/evalINDI.c

    r490 r642  
    347347{
    348348        char *t = tagXMLEle (root);
    349         char *d = findXMLAttValu (root, "device");
    350         char *n = findXMLAttValu (root, "name");
     349        const char *d = findXMLAttValu (root, "device");
     350        const char *n = findXMLAttValu (root, "name");
    351351        int nset = 0;
    352352        double v;
     
    397397
    398398        /* check special elements */
    399         t = findXMLAttValu (root, "state");
     399        t = (char *) findXMLAttValu (root, "state");
    400400        if (t[0]) {
    401401            sprintf (prop, "%s.%s._STATE", d, n);
     
    407407            }
    408408        }
    409         t = findXMLAttValu (root, "timestamp");
     409        t = (char *) findXMLAttValu (root, "timestamp");
    410410        if (t[0]) {
    411411            sprintf (prop, "%s.%s._TS", d, n);
  • BAORadio/libindi/libindi/tools/getINDIproperty.c

    r490 r642  
    446446                if (strcmp (tagXMLEle (root), defs[j].vec) == 0) {
    447447                    /* legal defXXXVector, check device */
    448                     char *dev = findXMLAttValu (root, "device");
     448                    char *dev = (char *) findXMLAttValu (root, "device");
    449449                    char *idev = srchs[i].d;
    450450                    if (idev[0] == WILDCARD || !strcmp (dev,idev)) {
    451451                        /* found device, check name */
    452                         char *nam = findXMLAttValu (root, "name");
     452                        char *nam = (char *) findXMLAttValu (root, "name");
    453453                        char *iprop = srchs[i].p;
    454454                        if (iprop[0] == WILDCARD || !strcmp (nam,iprop)) {
    455455                            /* found device and name, check perm */
    456                             char *perm = findXMLAttValu (root, "perm");
     456                            char *perm = (char *) findXMLAttValu (root, "perm");
    457457                            if (!wflag && perm[0] && !strchr (perm, 'r')) {
    458458                                if (verbose)
     
    491491            if (strcmp (iele, kwattr[i].keyword) == 0) {
    492492                /* just print the property state, not the element values */
    493                 char *s = findXMLAttValu (root, kwattr[i].indiattr);
     493                char *s = (char *) findXMLAttValu (root, kwattr[i].indiattr);
    494494                sp->ok = 1;                     /* progress */
    495495                if (onematch && justvalue)
     
    505505            if (!strcmp (tagXMLEle (ep), defone)) {
    506506                /* legal defXXX, check deeper */
    507                 char *enam = findXMLAttValu (ep, "name");
     507                char *enam = (char *) findXMLAttValu (ep, "name");
    508508                if (iele[0]==WILDCARD || !strcmp(enam,iele)) {
    509509                    /* found it! */
     
    556556
    557557        /* get format and length */
    558         format = findXMLAttValu (root, "format");
     558        format = (char *) findXMLAttValu (root, "format");
    559559        isz = !strcmp (&format[strlen(format)-2], ".z");
    560560
  • BAORadio/libindi/libindi/tools/setINDIproperty.c

    r504 r642  
    419419
    420420        /* check each set for matching device and property name, send if ok */
    421         rdev  = findXMLAttValu (root, "device");
    422         rprop = findXMLAttValu (root, "name");
     421        rdev  = (char *) findXMLAttValu (root, "device");
     422        rprop = (char *) findXMLAttValu (root, "name");
    423423        if (verbose > 1)
    424424            fprintf (stderr, "Read definition for %s.%s\n", rdev, rprop);
Note: See TracChangeset for help on using the changeset viewer.