Changeset 642
- Timestamp:
- Feb 24, 2012, 12:37:36 PM (12 years ago)
- Location:
- BAORadio/libindi/libindi
- Files:
-
- 67 edited
Legend:
- Unmodified
- Added
- Removed
-
BAORadio/libindi/libindi/BAOControl/Makefile
r619 r642 1 # Makefile for the socket programming example1 # Makefile 2 2 # 3 3 … … 7 7 CXXFLAGS = -g 8 8 9 BAOcontrol_objects = main.o baocontrol.o ClientSocket.o Socket.o filetools.o exception.o 10 9 BAOcontrol_objects = main.o baocontrol.o 11 10 12 11 all : BAOcontrol … … 14 13 15 14 BAOcontrol: $(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 18 23 19 Socket: Socket.cpp20 ClientSocket: ClientSocket.cpp21 24 baocontrol: baocontrol.cpp 22 filetools: filetools.cpp23 exception: exception.c24 25 main: main.cpp 25 26 -
BAORadio/libindi/libindi/BAOControl/baocontrol.cpp
r619 r642 4 4 /* Franck RICHARD */ 5 5 /* franckrichard033@gmail.com */ 6 /* Décembre 2011*/6 /* Février 2012 */ 7 7 /******************************/ 8 8 9 9 10 10 #include "baocontrol.h" 11 #include <termios.h> 12 #include <unistd.h> 11 13 12 14 13 15 14 16 15 /************************************************************************************** 17 **Constructeur 16 ** Constructeur de la classe BAOcontrol 17 ** 18 18 ***************************************************************************************/ 19 19 … … 23 23 24 24 // 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 params25 // ayant un fond blanc. pour un fond noir, mettre couleurs = 2 dans le fichier params 26 26 27 27 ChoixCouleurs=1; 28 28 29 30 Affiche("\n\n\n\n\n \ 29 //Affichage de la version du porgramme 30 31 AfficherLog("\n\n\n\n\n \ 31 32 ******************************************\n \ 32 33 * BAORadio Control *\n \ 33 34 * Laboratoire de l'Accélérateur Linéaire *\n \ 34 35 * *\n \ 35 * v0. 4 02/12/2011*\n \36 * v0.5 23/02/2012 *\n \ 36 37 * franckrichard033@gmail.com *\n \ 37 38 ******************************************\n\n\n", true); 38 39 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; 59 67 60 68 // chaines de caractÚres et tableaux 61 69 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 71 81 72 82 for (int i=0; i<MAXANTENNES; i++) 73 83 { 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(); 78 88 } 79 89 80 90 for (int i=0; i<MAXOBJETS; i++) 81 91 { 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"); 92 117 exit(1); 93 118 } 94 119 120 95 121 // Conversion de la latitude et de la longitude en radians 96 122 … … 103 129 double Longitude = Pi2 - ( a1 + a2 / 60.0 + a3 / 3600.0 ) * Pidiv180; 104 130 131 105 132 // Transfert de la latitude, longitude, pression, température à la classe Astro 106 133 … … 108 135 109 136 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 110 149 111 150 // Ouverture du socket avec indi_BAO … … 121 160 122 161 /************************************************************************************** 123 ** Destructeur 162 ** Destructeur de la classe BAOcontrol 163 ** 124 164 ***************************************************************************************/ 125 165 126 166 BAOcontrol::~BAOcontrol() 127 167 { 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 130 177 delete [] Antennes; 131 178 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 ) 136 185 { 137 186 XFreeGC(d, noir); … … 150 199 151 200 201 152 202 /************************************************************************************** 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 ** 204 205 ***************************************************************************************/ 205 206 … … 212 213 if ((d = XOpenDisplay(getenv("DISPLAY"))) == NULL) 213 214 { 214 Erreur ("Impossible de contacter le serveur\n\n");215 ErreurLog("Impossible de contacter le serveur graphique...\n\n"); 215 216 exit(1); 216 217 } 218 217 219 218 220 // crée une fenêtre … … 223 225 WhitePixel(d, DefaultScreen(d))); 224 226 227 225 228 // Création du double buffer 226 229 227 230 db = XCreatePixmap(d, w, larg_fenetre, haut_fenetre, DefaultDepth(d, DefaultScreen(d))); 228 231 232 229 233 // Chargement de la police de caractÚres 230 234 231 235 if ((fd = XLoadQueryFont(d, "fixed")) == NULL) 232 236 { 233 Erreur ("Impossible de charger la police fixed\n\n");237 ErreurLog("Impossible de charger la police fixed...\n\n"); 234 238 exit(1); 235 239 } 236 240 241 237 242 // Création des couleurs 238 243 239 244 gcv.font = fd->fid; 245 240 246 gcv.foreground = BlackPixel(d, DefaultScreen(d)); 241 247 noir = XCreateGC(d, w, GCFont | GCForeground, &gcv); 242 248 243 gcv.foreground = 200 *255;249 gcv.foreground = 200 * 255; 244 250 vert = XCreateGC(d, w, GCFont | GCForeground, &gcv); 245 251 246 gcv.foreground = 255 *256*256;252 gcv.foreground = 255 * 256 * 256; 247 253 rouge = XCreateGC(d, w, GCFont | GCForeground, &gcv); 248 254 249 gcv.foreground = 200 *256*256+200*256+200;255 gcv.foreground = 200 * 256 * 256 + 200 * 256 + 200; 250 256 gris = XCreateGC(d, w, GCFont | GCForeground, &gcv); 251 257 252 // Affichage de fenêtre 258 259 // Affichage de la fenêtre 253 260 254 261 XMapWindow(d, w); … … 267 274 chaine = new char [100]; 268 275 276 269 277 // On efface la fenêtre 270 278 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) 276 285 277 286 double h = GetHeure(); … … 282 291 double j = GetJour(); 283 292 double JJ = GetJJ(); 293 284 294 285 295 // on évite les affichages de l'heure du genre 12:56:60 ou 24:00:00 … … 298 308 } 299 309 310 300 311 //affichage de la date et de l'heure 301 312 … … 305 316 XDrawString(d, db, noir, 10, 10, chaine, strlen(chaine)); 306 317 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 308 320 309 321 if (run) … … 315 327 } 316 328 317 // affichage des cercles d'état 329 330 // affichage des cercles d'état des antennes 318 331 // vert = l'antenne fonctionne 319 332 // rouge = problÚme détecté sur l'antenne … … 338 351 339 352 XFillArc(d, db ,color, 10+i*30, 20+j*30, 15, 15, 0, 360*64); 353 340 354 XDrawArc(d, db ,noir, 10+i*30, 20+j*30, 15, 15, 0, 360*64); 341 355 } … … 343 357 344 358 345 // Affichage des messages d'indi_BAO346 // gÚre aussi le défilement347 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) 351 365 { 352 366 if ((logs[i].find("Err")!=string::npos) 353 367 || (logs[i].find("ALERTE")!=string::npos)) color=rouge; 354 368 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... 371 377 372 378 XCopyArea(d, db, w, noir, 0, 0, larg_fenetre, haut_fenetre, 0, 0); 379 373 380 374 381 // On force le rafraichissement de l'écran … … 380 387 381 388 389 382 390 /************************************************************************************** 383 391 ** Gestion des événements affectant la fenêtre graphique 392 ** 384 393 ***************************************************************************************/ 385 394 … … 403 412 404 413 414 405 415 /************************************************************************************** 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 ** 407 418 ***************************************************************************************/ 408 419 … … 410 421 { 411 422 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 413 427 414 428 *client_socket >> reponse; 415 416 // printf("%s\n", reponse.c_str());417 429 418 430 do 419 431 { 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) 421 435 { 422 436 // On ne garde que la partie intéressante 423 // La partie "message="... 437 // La partie qui suit "message="... 438 424 439 reponse = reponse.substr(reponse.find("message") + 9); 425 440 441 //(on en garde une trace) 442 426 443 memreponse = reponse; 427 444 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("\"")); 430 448 431 449 // 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" 433 452 434 453 if (reponse.find(". (Antennes connectees")!=string::npos) … … 437 456 decomp = decomp.substr(decomp.rfind(".")+1); 438 457 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++) 444 461 { 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 } 448 470 } 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 452 473 453 474 if (!test) 454 475 { 455 476 Antennes[numAntennes].ip = atoi(decomp.c_str()); 477 456 478 Antennes[numAntennes++].ok = 1; 457 479 } … … 459 481 460 482 // 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)) 464 488 { 465 489 decomp = reponse.substr(0, reponse.find(" :")); … … 468 492 for (int i=0; i<numAntennes; i++) 469 493 { 494 // On identifie l'antenne dans le tableau Antennes et on change son état 495 470 496 if (atoi(decomp.c_str()) == Antennes[i].ip) 471 497 { … … 475 501 } 476 502 477 // On sauvegarde le message dans le tableau logs503 // On sauvegarde le message dans le fichier logs mais on ne l'affiche pas 478 504 479 505 stringstream os; … … 481 507 os << lognum << " : " << reponse; 482 508 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(); 486 512 487 513 reponse = memreponse; 488 } 489 else reponse ="";490 491 492 } while ( reponse != "" );493 494 495 496 514 } 515 else reponse = ""; 516 517 518 } while ( reponse != "" ); 519 520 // on actualise la fenêtre 521 522 Dessiner(); 497 523 498 524 // on envoie un message pour actualiser la fenêtre graphique … … 505 531 /************************************************************************************** 506 532 ** 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 ** 507 535 ***************************************************************************************/ 508 536 … … 529 557 duree++; 530 558 } 531 while (reponse.length() == 0 && duree <10 ); // on attend un message pendant 10 ms max559 while (reponse.length() == 0 && duree < 20 ); // on attend un message pendant 10 ms max 532 560 533 561 // on ajoute tous les messages reçus dans memmreponse … … 555 583 memreponse = memreponse.substr(0, memreponse.find("\"")); 556 584 557 Erreur ("Réponse du pilote indi_BAO :" + memreponse + "\n\n");585 ErreurLog("Réponse du pilote indi_BAO :" + memreponse + "\n\n"); 558 586 } 559 587 … … 565 593 566 594 595 567 596 /************************************************************************************** 568 597 ** Calcul du jour julien et du temps sidéral local 598 ** 569 599 ***************************************************************************************/ 570 600 571 void BAOcontrol::Update ()601 void BAOcontrol::UpdateTime() 572 602 { 603 time_t t; 573 604 struct tm date; 574 time_t t;575 605 struct timeval tv; 576 struct timezone tz;577 606 578 607 // On récupÚre la date et l'heure depuis l'horloge du systÚme … … 580 609 time(&t); 581 610 date=*gmtime(&t); 582 gettimeofday(&tv, &tz);611 gettimeofday(&tv, NULL); 583 612 584 613 double Annee = (double)date.tm_year + 1900.0; … … 590 619 double UTCP = 0.0;//(double)date.tm_isdst; 591 620 592 /*Annee=2011;593 Mois=6;594 Jour=17;595 Heu=15;596 Min=53.0;597 Sec=00.0;*/598 599 621 // On actualise la date et l'heure dans la classe Astro 600 622 601 623 DefinirDateHeure(Annee, Mois, Jour, Heu, Min, Sec); 602 624 603 // On lance les calculs 625 // On lance les calculs (Temps sidéral local etc...) 604 626 605 627 CalculTSL(); … … 607 629 608 630 631 609 632 /************************************************************************************** 610 633 ** 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 ** 614 638 ***************************************************************************************/ 615 639 … … 617 641 { 618 642 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' 621 646 while (NoExit) 622 647 { 623 // On actualise le jour julien et le temps sidéral local624 625 Update ();648 // On actualise le jour julien et le temps sidéral local 649 650 UpdateTime(); 626 651 627 652 // On récupÚre le jour julien … … 632 657 // Faut-il executer un fichier de mouvements ? 633 658 634 if (run && numobjets >1 && runnum<numobjets)635 { 636 // On lance le mouvement numéro runnum si la date correspondau début659 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 637 662 // de son exécution et que ce mouvement n'a pas été encore réalisé 638 663 639 if ( JJ >= objets[runnum].JJ && !objets[runnum].exec)664 if ( JJ >= objets[runnum].JJ && !objets[runnum].exec ) 640 665 { 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); 644 669 645 670 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 ); 656 682 } 657 683 … … 669 695 if ( runnum + 1 >= numobjets ) 670 696 { 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); 672 698 673 699 // on réaffiche le prompt … … 685 711 // On sort du programme dans le cas BAOControl -r fileName 686 712 687 NoExit =!exitrun;713 NoExit = !exitrun; 688 714 } 689 715 else … … 702 728 Dessiner(); 703 729 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 704 746 // pause de 100 ms 705 747 … … 708 750 709 751 // l'utilisateur a tapé exit... On sort du thread... 710 711 752 712 753 pthread_exit (0); … … 730 771 ** chaine2 = "25:10:10" 731 772 ** 732 ** DecompositionCommande("goto messier 1","goto", &chaine1, NULL) (avec chaine2=NULL L)773 ** DecompositionCommande("goto messier 1","goto", &chaine1, NULL) (avec chaine2=NULL) 733 774 ** retourne chaine1 = "messier 1" 734 775 ** chaine2 = NULL 776 ** 735 777 ***************************************************************************************/ 736 778 … … 762 804 763 805 // puis on prend le deuxiÚme bloc -> c'est la chaine2 806 764 807 pos = chaine.find(" "); 765 808 … … 781 824 *chaine1 = chaine; 782 825 } 783 } 826 } else return false; 784 827 785 828 return true; … … 790 833 /************************************************************************************** 791 834 ** Envoie la longitude et la latitude du lieu d'observation au pilote indi_BAO 835 ** 792 836 ***************************************************************************************/ 793 837 … … 795 839 { 796 840 // 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 799 842 800 843 try … … 811 854 if (!VerifReponse("name=\"GEOGRAPHIC_COORD\" state=\"Ok\"")) 812 855 { 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"); 814 857 815 858 return false; … … 821 864 catch ( SocketException& e ) 822 865 { 823 Erreur("Exception was caught:" + e.description() + "\n"); 866 ErreurLog("Exception was caught:" + e.description() + "\n"); 867 824 868 return false; 825 869 } 826 870 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); 828 872 829 873 return true; … … 831 875 832 876 877 /************************************************************************************** 878 ** Transmet la pression et la température au pilote indi_BAO 879 ** 880 ***************************************************************************************/ 881 882 bool 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 930 bool 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 988 bool 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 833 1026 834 1027 /************************************************************************************** 835 1028 ** Place les antennes en position de repos 1029 ** 836 1030 ***************************************************************************************/ 837 1031 … … 848 1042 if (!VerifReponse("PARK OK")) 849 1043 { 850 Erreur ("La commande PARK a échoué.\n\n");;1044 ErreurLog("La commande PARK a échoué.\n\n");; 851 1045 852 1046 return false; … … 855 1049 catch ( SocketException& e) 856 1050 { 857 Erreur("Exception was caught:" + e.description() + "\n"); 1051 ErreurLog("Exception was caught:" + e.description() + "\n"); 1052 858 1053 return false; 859 1054 } 860 1055 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); 862 1057 863 1058 return true; … … 868 1063 /************************************************************************************** 869 1064 ** Annule le mouvement en cours 1065 ** 870 1066 ***************************************************************************************/ 871 1067 … … 882 1078 if (!VerifReponse("ABORT OK")) 883 1079 { 884 Erreur ("L'annulation a échoué.\n\n");1080 ErreurLog("L'annulation a échoué.\n\n"); 885 1081 886 1082 return false; … … 889 1085 catch ( SocketException& e) 890 1086 { 891 Erreur("Exception was caught:" + e.description() + "\n"); 1087 ErreurLog("Exception was caught:" + e.description() + "\n"); 1088 892 1089 return false; 893 1090 } 894 1091 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); 896 1093 897 1094 return true; … … 903 1100 ** Diriger l'antenne vers les coordonnées ar et dec et suivre l'objet 904 1101 ** en activant le mode transit ou tracking. 1102 ** 905 1103 ** si J2000 == true, cela signifie que les coordonnées ar et dec sont données dans le 906 1104 ** 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 ** 908 1109 ***************************************************************************************/ 909 1110 910 1111 bool BAOcontrol::Goto(string ar, string dec, bool Transit, bool J2000) 911 1112 { 1113 double arf, decf; 1114 double azi, hau; 912 1115 float ar1, ar2, ar3; 913 1116 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 925 1118 926 1119 // Conversion de l'AD et de la déclinaison en radians 927 1120 928 1121 Decomposition(ar, 2, &ar1, &ar2, &ar3); 1122 929 1123 Decomposition(dec, 0, &dec1, &dec2, &dec3); 930 1124 931 1125 arf = ( ar1 + ar2 / 60.0 + ar3 / 3600.0 ) * 15.0 * Pidiv180; 932 1126 decf = ( fabs(dec1) + dec2 / 60.0 + dec3 / 3600.0 ) * Pidiv180; 933 1127 934 if (dec[0] =='-') decf = -decf;1128 if (dec[0] == '-') decf = -decf; 935 1129 936 1130 // calculs pupplémentaires pour se ramener … … 952 1146 // on en informe l'utilisateur 953 1147 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 969 1152 970 1153 // On transmet les coordonnées au pilote BAO … … 986 1169 if (!VerifReponse("name=\"ON_COORD_SET\"")) 987 1170 { 988 Erreur ("Le changement de mode TRANSIT/TRACKING a échoué.\n\n");1171 ErreurLog("Le changement de mode TRANSIT/TRACKING a échoué.\n\n"); 989 1172 990 1173 return false; … … 1002 1185 if (!VerifReponse("name=\"EQUATORIAL_EOD_COORD_REQUEST\"")) 1003 1186 { 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"); 1005 1188 1006 1189 return false; … … 1009 1192 catch ( SocketException& e) 1010 1193 { 1011 Erreur("Exception was caught:" + e.description() + "\n"); 1194 ErreurLog("Exception was caught:" + e.description() + "\n"); 1195 1012 1196 return false; 1013 1197 } 1014 1198 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 1017 1202 return true; 1018 1203 } … … 1041 1226 if (!VerifReponse("BAORadio is online")) 1042 1227 { 1043 Erreur ("La connexion a échoué.\n\n");1228 ErreurLog("La connexion a échoué.\n\n"); 1044 1229 1045 1230 return false; … … 1050 1235 if (!VerifReponse("BAORadio is offline")) 1051 1236 { 1052 Erreur ("La déconnexion a échoué.\n\n");1237 ErreurLog("La déconnexion a échoué.\n\n"); 1053 1238 1054 1239 return false; … … 1059 1244 catch ( SocketException& e ) 1060 1245 { 1061 Erreur("Exception was caught:" + e.description() + "\n"); 1246 ErreurLog("Exception was caught:" + e.description() + "\n"); 1247 1062 1248 return false; 1063 1249 } … … 1065 1251 if (connect) 1066 1252 { 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); 1068 1256 1069 1257 EnvoyerCoordGeographiques(); 1258 1259 EnvoyerPressionTemperature(); 1260 1261 EnvoyerDelaisModesTransitEtTracking(); 1262 1263 EnvoyerMethodeAlignement(); 1070 1264 } 1071 1265 else 1072 1266 { 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); 1074 1268 } 1075 1269 … … 1080 1274 /************************************************************************************** 1081 1275 ** 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 1082 1278 ***************************************************************************************/ 1083 1279 … … 1086 1282 static struct termios cooked; 1087 1283 static int raw_actif = 0; 1088 1284 1089 1285 if (raw_actif == activer) 1090 1286 return; 1091 1287 1092 1288 if (activer) 1093 1289 { 1094 1290 struct termios raw; 1095 1291 1096 1292 tcgetattr(STDIN_FILENO, &cooked); 1097 1293 1098 1294 raw = cooked; 1099 1295 cfmakeraw(&raw); … … 1102 1298 else 1103 1299 tcsetattr(STDIN_FILENO, TCSANOW, &cooked); 1104 1300 1105 1301 raw_actif = activer; 1106 1302 } … … 1109 1305 /************************************************************************************** 1110 1306 ** 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...) 1111 1314 ***************************************************************************************/ 1112 1315 1113 bool BAOcontrol::Alignement (string ip)1316 bool BAOcontrol::AlignementAntenneIP( string ip ) 1114 1317 { 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; 1176 1321 1177 1322 stringstream os; 1178 1323 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; 1202 1619 } 1203 1620 … … 1208 1625 1209 1626 /************************************************************************************** 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 ** 1422 1629 ***************************************************************************************/ 1423 1630 … … 1428 1635 bool exec = LectureFichierMouvements(fichier); 1429 1636 1430 Update ();1637 UpdateTime(); 1431 1638 1432 1639 if ( exec && numobjets>1 ) … … 1436 1643 if (objets[numobjets-1].JJ + objets[numobjets-1].Duree / 3600.0 / 24.0 < GetJJ()) 1437 1644 { 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 1440 1648 return false; 1441 1649 } 1442 1650 else 1443 1651 { 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; 1446 1654 } 1447 1655 } 1448 1656 else 1449 1657 { 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"); 1451 1659 NoExit=!exitrun; 1660 1452 1661 return false; 1453 1662 } … … 1461 1670 ** Décomposition et vérification des dates, heures, AD et déclinaisons 1462 1671 ** 1463 ** type = 0 -> Déclinaison/latitude1672 ** type = 0 -> chaine contient une déclinaison ou une latitude 1464 1673 ** type = 1 -> longitude 1465 1674 ** type = 2 -> AD ou heure 1466 1675 ** type = 3 -> date 1467 1676 ** 1468 ** Exemple de D ecomposition("15:23:12", 2, a, b, c) retourne a=15, b=23, c=121677 ** Exemple de Décomposition("15:23:12", 2, a, b, c) retourne a=15, b=23, c=12 1469 1678 ** si la chaine a un format incorrect, la fct retourne false 1679 ** 1470 1680 ***************************************************************************************/ 1471 1681 … … 1473 1683 { 1474 1684 string car, s; 1685 1475 1686 float a, b, c; 1476 1687 1477 1688 // pour les heures et les coordonnées, on attend ":" comme caractÚre séparateur, sinon 1478 // on attend d'avoir des "/"pour une date1479 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=":"; 1481 1692 1482 1693 // Y a-t-il 2 caractÚres ':' ou '/' dans la chaine ? 1483 1694 // C'est indispensable dans tous les cas 1484 1695 1485 int test=0; 1696 int test = 0; 1697 1486 1698 for (int i=0; i<chaine.length(); i++) if (chaine[i] == car[0]) test++; 1699 1487 1700 if (test<2) return false; 1488 1701 … … 1493 1706 a = atoi(s.c_str()); 1494 1707 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); 1496 1709 1497 1710 b = atoi(s.c_str()); … … 1499 1712 s = chaine.substr(chaine.rfind(car)+1); 1500 1713 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; 1502 1717 1503 1718 //vérification de la cohérence des infos contenues dans la chaine … … 1506 1721 { 1507 1722 // 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; 1509 1724 // 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; 1511 1726 // 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; 1513 1728 // pour les minutes 1514 if ( b<0.0 || b>59.0 ) return false;1729 if ( b < 0.0 || b> 59.0 ) return false; 1515 1730 //pour les secondes 1516 if ( c<0.0 || c>=60.0) return false;1731 if ( c < 0.0 || c>=60.0 ) return false; 1517 1732 } 1518 1733 else 1519 1734 { 1520 1735 //pour les jours 1521 if ( a<0.0 || a>31.0) return false;1736 if ( a < 0.0 || a > 31.0 ) return false; 1522 1737 //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; 1529 1744 1530 1745 return true; … … 1537 1752 ** identification des commandes entrées par l'utilisateur 1538 1753 ** puis exécution des commandes 1754 ** 1539 1755 ***************************************************************************************/ 1540 1756 … … 1544 1760 stringstream os; 1545 1761 1546 // Permet de savoir si la derniÚre saisie del'utilisateur1762 // Permet de savoir si la derniÚre commande saisie par l'utilisateur 1547 1763 // est une commande valide 1764 1548 1765 bool CommandeOK = false; 1549 1766 … … 1553 1770 if ( chaine.find("goto") != string::npos ) 1554 1771 { 1555 CommandeOK = true;1556 1772 1557 1773 // L'utilisateur a fait suivre la commande goto de l'indication J2000 … … 1559 1775 if (J2000 = (chaine.find("j2000") != string::npos)) 1560 1776 { 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 J20001777 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") 1564 1780 1565 1781 chaine = chaine.substr(0, chaine.find("J2000")); 1566 1782 } 1567 1783 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)) 1569 1787 { 1570 1788 // L'utilisateur a indiqué deux coordonnées valides -> on exécute le goto 1789 1790 CommandeOK = true; 1571 1791 1572 1792 Goto(ar, de, Transit, J2000); … … 1577 1797 // puis on envoie les coordonnées de l'objet au pilote indi_BAO 1578 1798 1799 CommandeOK = true; 1800 1579 1801 if ((DecompositionCommande(chaine, "goto", &objet, NULL)) && (chaine.find(":") == string::npos)) 1580 1802 { 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 } 1599 1840 } 1600 1841 else 1601 1842 { 1602 Erreur ("Erreur goto : le format de la commande est goto AD DEC\n \1603 L 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 \ 1605 1846 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 \ 1607 1848 Ne pas préciser dans ce cas J2000.\n\n"); 1608 1849 } … … 1622 1863 if (chaine.find("run") != string::npos) 1623 1864 { 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); 1629 1870 1630 1871 return; … … 1644 1885 else 1645 1886 { 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"); 1647 1888 } 1648 1889 } … … 1657 1898 } 1658 1899 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) 1662 1905 { 1663 1906 CommandeOK = true; 1664 1907 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) 1673 1914 { 1674 1915 CommandeOK = true; 1675 1916 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) 1684 1928 { 1685 1929 CommandeOK = true; 1686 1930 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"; 1713 1934 os << "Port du serveur Indi = " << Port << "\n\n"; 1714 1935 os << "Pression atmosphérique = " << Pression << " mBar\n"; 1715 1936 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); 1719 1961 } 1720 1962 … … 1725 1967 string objet; 1726 1968 1969 bool CestUneEtoile = false; 1970 1727 1971 CommandeOK = true; 1728 1972 1729 1973 if (DecompositionCommande(chaine, "search", &objet, NULL)) 1730 1974 { 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 1735 1995 // correction de l'alignement d'une antenne par rapport à l'objet visé 1736 1996 … … 1743 2003 if (DecompositionCommande(chaine, "align", &antenne, NULL)) 1744 2004 { 1745 Alignement (antenne);2005 AlignementAntenneIP(antenne); 1746 2006 } 1747 2007 else 1748 2008 { 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 1752 2202 1753 2203 // Aide du programme … … 1759 2209 cout << endl; 1760 2210 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; 1787 2241 1788 2242 cout << endl; … … 1791 2245 // Bye ! 1792 2246 1793 if (chaine.find("exit") !=string::npos)2247 if (chaine.find("exit") != string::npos) 1794 2248 { 1795 2249 CommandeOK = true; 1796 2250 1797 Abort(); 2251 if ( numAntennes > 0 ) Abort(); 2252 2253 usleep(500000); 1798 2254 1799 2255 Connect(false); … … 1804 2260 // La commande n'a pas été identifiée ! 1805 2261 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"); 1807 2263 } 2264 1808 2265 1809 2266 1810 2267 /************************************************************************************** 1811 2268 ** 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 ** 1813 2272 ***************************************************************************************/ 1814 2273 1815 Coordonnees BAOcontrol::ServeurNED(string objet)2274 CoordonneesHoraires BAOcontrol::ServeurNED(string objet) 1816 2275 { 1817 Coordonnees reponse;2276 CoordonneesHoraires reponse; 1818 2277 stringstream send; 1819 2278 … … 1833 2292 // Effacer le fichier result s'il existe dans le répertoire du programme 1834 2293 1835 if ((pFile = fopen ("result ", "r")) != NULL )2294 if ((pFile = fopen ("result_recherche_bao", "r")) != NULL ) 1836 2295 { 1837 2296 fclose (pFile); 1838 rc = system( "rm result");2297 rc = system( "rm -rf result_recherche_bao"); 1839 2298 } 1840 2299 … … 1842 2301 // On sauvegarde le résultat dans le fichier result 1843 2302 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="; 1845 2304 send << objet; 1846 2305 send << "&extend=no&hconst=73&omegam=0.27&omegav=0.73&corr_z=1&out_csys=Equatorial&out_equinox=J2000.0"; 1847 2306 send << "&obj_sort=RA+or+Longitude&of=ascii_bar&zv_breaker=30000.0&list_limit=5&img_stamp=NO\""; 1848 2307 1849 Affiche ("Envoi de la requête au serveur NED...\n", true);2308 AfficherLog("Envoi de la requête au serveur NED...\n", true); 1850 2309 1851 2310 // on lance la requête … … 1857 2316 if (WEXITSTATUS(rc) ==-1 || WEXITSTATUS(rc) ==127) 1858 2317 { 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"); 1860 2319 } 1861 2320 else 1862 2321 { 1863 // On a obtenu quelque chose2322 // On a reçu quelque chose 1864 2323 1865 2324 int nbRead = 0; … … 1876 2335 // On ouvre le fichier result 1877 2336 1878 pFile = fopen ("result ", "r");2337 pFile = fopen ("result_recherche_bao", "r"); 1879 2338 1880 2339 if (pFile) … … 1889 2348 // Le fichier contient une indication d'erreur -> pas de réponse exploitable 1890 2349 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); 1892 2351 } 1893 2352 else … … 1895 2354 // on analyse la réponse 1896 2355 1897 Affiche ("\nRéponse du serveur :\n", true);2356 AfficherLog("\nRéponse du serveur :\n", true); 1898 2357 1899 2358 do … … 1905 2364 { 1906 2365 string chaine = (string)pBuf; 1907 string chaine2;1908 2366 1909 2367 chaine=chaine.substr(chaine.find('|')+1); … … 1911 2369 // affiche le nom de l'objet dans le serveur NED 1912 2370 1913 Affiche (chaine.substr(0, chaine.find('|')) + "\n", true);2371 AfficherLog(chaine.substr(0, chaine.find('|')) + "\n", true); 1914 2372 1915 2373 chaine = chaine.substr(chaine.find('|') + 1); 1916 2374 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 1917 2387 chaine2 = chaine.substr(0, chaine.find('|')); 1918 2388 1919 double ar = atof(chaine2.c_str());1920 1921 // affiche l'ascension droite1922 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 1931 2389 double dec = atof(chaine2.c_str()); 1932 2390 1933 2391 // on affiche la déclinaison 1934 2392 1935 Affiche ("Dec (J2000) = " + DHMS(dec, false)+"\n", true);2393 AfficherLog("Dec (J2000) = " + DHMS(dec, false)+"\n", true); 1936 2394 1937 2395 reponse.dec = DHMS(dec, false); … … 1945 2403 else 1946 2404 { 1947 Erreur ("\nLa connexion semble impossible avec le serveur NED !\n\n");2405 ErreurLog("\nLa connexion semble impossible avec le serveur NED !\n\n"); 1948 2406 } 1949 2407 … … 1952 2410 else 1953 2411 { 1954 Erreur ("\nLa connexion semble impossible avec le serveur NED !\n\n");2412 ErreurLog("\nLa connexion semble impossible avec le serveur NED !\n\n"); 1955 2413 } 1956 2414 1957 2415 delete [] pBuf; 1958 2416 1959 Affiche ("\n", true);2417 AfficherLog("\n", true); 1960 2418 } 1961 2419 … … 1973 2431 { 1974 2432 int nbchar = 0; 2433 1975 2434 char c; 1976 2435 … … 2001 2460 /************************************************************************************** 2002 2461 ** chargement des paramÚtres contenus dans le fichier params 2462 ** 2003 2463 ***************************************************************************************/ 2004 2464 … … 2011 2471 2012 2472 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); 2015 2479 2016 2480 … … 2026 2490 { 2027 2491 LatitudeChar = (string)value; 2028 delete [] value;2029 Affiche ("latitude = " + LatitudeChar +"\n", true);2492 SAFEDELETE_TAB(value); 2493 AfficherLog("latitude = " + LatitudeChar +"\n", true); 2030 2494 } 2031 2495 else 2032 2496 { 2033 Erreur("La latitude est incorrecte !\n"); 2497 ErreurLog("La latitude est incorrecte !\n"); 2498 2034 2499 return false; 2035 2500 } … … 2042 2507 { 2043 2508 LongitudeChar = (string)value; 2044 delete [] value;2045 Affiche ("longitude = " + LongitudeChar +"\n\n", true);2509 SAFEDELETE_TAB(value); 2510 AfficherLog("longitude = " + LongitudeChar +"\n\n", true); 2046 2511 } 2047 2512 else 2048 2513 { 2049 Erreur("La longitude est incorrecte !\n"); 2514 ErreurLog("La longitude est incorrecte !\n"); 2515 2050 2516 return false; 2051 2517 } … … 2062 2528 { 2063 2529 Serveur = (string)value; 2064 delete [] value;2065 Affiche ("serveur = " + Serveur +"\n", true);2530 SAFEDELETE_TAB(value); 2531 AfficherLog("serveur = " + Serveur +"\n", true); 2066 2532 } 2067 2533 else 2068 2534 { 2069 Erreur("Nom du serveur invalide !\n"); 2535 ErreurLog("Nom du serveur invalide !\n"); 2536 2070 2537 return false; 2071 2538 } … … 2077 2544 { 2078 2545 Port = (string)value; 2079 delete [] value;2080 Affiche ("port = " + Port +"\n\n", true);2546 SAFEDELETE_TAB(value); 2547 AfficherLog("port = " + Port +"\n\n", true); 2081 2548 } 2082 2549 else 2083 2550 { 2084 Erreur("Numéro de port incorrect !\n"); 2551 ErreurLog("Numéro de port incorrect !\n"); 2552 2085 2553 return false; 2086 2554 } … … 2097 2565 { 2098 2566 Pression = atof(value); 2099 delete [] value;2567 SAFEDELETE_TAB(value); 2100 2568 os << "pression = " << Pression << endl; 2101 Affiche (&os, true);2569 AfficherLog(&os, true); 2102 2570 } 2103 2571 else 2104 2572 { 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 2107 2576 return false; 2108 2577 } … … 2112 2581 if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str())) 2113 2582 { 2114 Temperature =atof(value);2115 delete [] value;2583 Temperature = atof(value); 2584 SAFEDELETE_TAB(value); 2116 2585 os << "température = " << Temperature << endl << endl; 2117 Affiche (&os, true);2586 AfficherLog(&os, true); 2118 2587 } 2119 2588 else 2120 2589 { 2121 Erreur("La température est incorrecte !\n"); 2590 ErreurLog("La température est incorrecte !\n"); 2591 2122 2592 return false; 2123 2593 } … … 2134 2604 { 2135 2605 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); 2138 2608 } 2139 2609 else 2140 2610 { 2141 Erreur("Le paramÚtre mode est incorrect !\n"); 2611 ErreurLog("Le paramÚtre mode est incorrect !\n"); 2612 2142 2613 return false; 2143 2614 } … … 2149 2620 if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str())) 2150 2621 { 2151 delaitransit =atoi(value);2152 delete [] value;2622 delaitransit = atoi(value); 2623 SAFEDELETE_TAB(value); 2153 2624 os << "delai transit = " << delaitransit << " sec" << endl; 2154 Affiche (&os, true);2625 AfficherLog(&os, true); 2155 2626 } 2156 2627 else 2157 2628 { 2158 Erreur("Le paramÚtre delai_transit est incorrect !\n"); 2629 ErreurLog("Le paramÚtre delai_transit est incorrect !\n"); 2630 2159 2631 return false; 2160 2632 } … … 2165 2637 if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str())) 2166 2638 { 2167 delaitracking =atoi(value);2168 delete [] value;2639 delaitracking = atoi(value); 2640 SAFEDELETE_TAB(value); 2169 2641 os << "delai tracking = " << delaitracking << " sec" << endl << endl; 2170 Affiche (&os, true);2642 AfficherLog(&os, true); 2171 2643 } 2172 2644 else 2173 2645 { 2174 Erreur("Le paramÚtre delai_tracking est incorrect !\n"); 2646 ErreurLog("Le paramÚtre delai_tracking est incorrect !\n"); 2647 2175 2648 return false; 2176 2649 } … … 2187 2660 { 2188 2661 ChoixCouleurs=atoi(value); 2189 delete [] value;2662 SAFEDELETE_TAB(value); 2190 2663 } 2191 2664 else 2192 2665 { 2193 2666 /*os << "Le paramÚtre couleurs est incorrect !" << endl; 2194 Erreur (os.str());2667 ErreurLog(os.str()); 2195 2668 return false;*/ 2196 2669 } … … 2198 2671 return true; 2199 2672 } 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 2687 bool 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 2916 bool 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 2200 3048 2201 3049 … … 2227 3075 if (argc == 1) cout << "Tapez help pour obtenir la liste des commandes disponibles.\n" << endl << endl; 2228 3076 3077 2229 3078 // On lance la fenêtre graphique 2230 3079 … … 2232 3081 2233 3082 XSelectInput(d,w, ExposureMask ); 3083 2234 3084 2235 3085 // On lance le thread pour gérer la fenêtre graphique … … 2237 3087 2238 3088 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"); 2240 3090 return -1; 2241 3091 } 2242 3092 2243 3093 2244 2245 3094 // si on a utilisé l'option -r en ligne de commande 2246 // alors on charge et on lance l'exécution d'unfichier de mouvements3095 // alors on charge et on execute le fichier de mouvements 2247 3096 2248 3097 if (argc == 3) … … 2263 3112 else 2264 3113 { 2265 Erreur ("Usage incorrect\n\n");3114 ErreurLog("Usage incorrect\n\n"); 2266 3115 } 2267 3116 } … … 2273 3122 { 2274 3123 // Prompt 2275 ChoixCouleurs==1 ? cout << blue1 : cout << blue2; 3124 ChoixCouleurs==1 ? IDLog(blue2) : IDLog(blue1); 3125 2276 3126 cout << '>'; 3127 2277 3128 // saisie 2278 3129 getline(cin, chaine); 2279 ChoixCouleurs==1 ? cout << grey1 : cout << grey2; 3130 3131 ChoixCouleurs==1 ? IDLog(grey1) : IDLog(grey2); 2280 3132 2281 3133 // on met en minuscules … … 2283 3135 2284 3136 // on décode et exécute les commandes 2285 DecodageEntreesUtilisateur(chaine); 2286 3137 DecodageEntreesUtilisateur(chaine); 3138 2287 3139 } 2288 3140 while (NoExit); 2289 3141 2290 3142 pthread_join(th1 ,NULL); 2291 //pthread_detach(th1);2292 3143 } 2293 3144 2294 3145 return 0; 2295 3146 } 3147 3148 3149 /************************************************************************************** 3150 ** Le fichier file existe-t-il et n'est-il pas vide ? 3151 ** 3152 **************************************************************************************/ 3153 3154 bool 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 7 7 8 8 9 #include <iostream> 10 #include <string.h> 11 #include <sstream> 12 #include "ClientSocket.h" 13 #include "SocketException.h" 9 #include "math.h" 10 14 11 #include <stdio.h> 15 12 #include <stdlib.h> 16 13 #include <pthread.h> 17 14 #include <X11/Xlib.h> 18 #include "filetools.h" 19 #include "../drivers/telescope/astro.h" 20 #include "math.h" 15 21 16 #include <time.h> 22 17 #include <unistd.h> 23 18 #include <sys/time.h> 19 #include <termios.h> 24 20 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" 26 27 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 tableaux40 41 #define MAXLOG 100042 #define MAXOBJETS 10043 #define MAXANTENNES 5044 45 46 // dimensions de la fenêtre graphique47 48 #define haut_fenetre 10+22*1049 #define larg_fenetre 60550 28 51 29 using namespace std; 52 30 53 31 54 struct DefAntenne 32 // ParamÚtres des étoiles utilisées pour l'alignement des antennes 33 34 struct DefEtoiles 55 35 { 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 ? 74 45 }; 75 46 76 47 77 48 78 class BAOcontrol : public Astro 49 // structure définissant les paramÚtres des antennes 50 51 struct 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 68 struct 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 82 class BAOcontrol : public Astro, public Logs 79 83 { 80 84 … … 83 87 ~BAOcontrol(); 84 88 89 //Gestion du thread 90 85 91 void *my_thread_process (); 92 93 // intialise la clase 94 86 95 int init(int argc, char **argv); 87 96 88 97 98 89 99 private: 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 94 103 void initialiserFenetre(); 95 104 void Dessiner(); 96 105 void rouler(); 106 107 108 //communications entre les antennes et le microcontrÃŽleur 109 97 110 void LireReponse(); 98 111 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); 102 118 bool EnvoyerCoordGeographiques(); 119 bool EnvoyerPressionTemperature(); 120 bool EnvoyerDelaisModesTransitEtTracking(); 121 bool EnvoyerMethodeAlignement(); 103 122 bool Park(); 104 123 bool Abort(); 105 124 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 ); 107 132 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); 109 146 void DecodageEntreesUtilisateur(string chaine); 110 147 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);115 148 149 116 150 117 151 118 152 // Variables globales 119 153 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 123 155 124 156 string logs[MAXLOG]; // Sauvegarde de toutes les actions et réponses dans un tableau logs … … 130 162 int numobjets; // Nbre d'objets dans le dernier fichier de mouvements chargé 131 163 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 132 167 133 168 double Pression; // Pression atmosphérique en mBar … … 139 174 bool exitrun; // doit-on sortir du programme à la fin de l'execution de la commande run ? 140 175 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é ? 141 178 142 179 struct DefAntenne *Antennes; // Sauvegarde de la situation actuelle de l'antenne i 143 180 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 144 182 145 183 string LatitudeChar; // Latitude du lieu d'observation. Chargée depuis le fichier de configuration 146 184 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 localhost185 string Serveur; // Nom ou IP du serveur faisant tourner indi_BAO. Par defaut contient 'localhost' 148 186 string Port; // Port utilisé pour connecter le serveur indi_BAO 149 187 … … 153 191 Window w; // fenêtre graphique 154 192 Pixmap db; // copie de la fenêtre pour permettre une actualisation sans scintillement 193 155 194 GC noir, vert, rouge, gris; // couleurs utilisées dans la fenêtre graphique 156 157 195 }; 158 196 -
BAORadio/libindi/libindi/BAOControl/main.cpp
r504 r642 9 9 appli->init(argc, argv); 10 10 11 delete appli; 12 11 delete appli; 13 12 } -
BAORadio/libindi/libindi/BAOTest/BAOtest_main.cpp
r504 r642 5 5 ***************************************************************************************/ 6 6 7 #include "ClientSocket.h" 8 #include "ServerSocket.h" 9 #include "SocketException.h" 7 #include "../communs/ClientSocket.h" 8 #include "../communs/SocketException.h" 10 9 #include <iostream> 11 10 #include <string> … … 128 127 #define ERREURS 50 129 128 130 int main ( int argc, intargv[] )129 int main ( int argc, char *argv[] ) 131 130 { 132 131 Position Pos, Pos2; -
BAORadio/libindi/libindi/BAOTest/Makefile
r495 r642 2 2 # 3 3 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 4 BAOtest_objects = BAOtest_main.o 7 5 8 6 9 all : simple_server simple_clientBAOtest7 all : BAOtest 10 8 11 simple_server: $(simple_server_objects) 12 g++ -o simple_server $(simple_server_objects) 9 BAOtest: $(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 13 13 14 14 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.cpp23 ServerSocket: ServerSocket.cpp24 15 ClientSocket: ClientSocket.cpp 25 simple_server_main: simple_server_main.cpp26 simple_client_main: simple_client_main.cpp27 16 BAOtest_main: BAOtest_main.cpp 28 17 29 18 clean: 30 rm -f *.o *.cpp~ *.h~ simple_server simple_client BAOtest 19 rm -f *.o *.cpp~ *.h~ BAOtest 20 21 install: 22 cp BAOtest /usr/bin -
BAORadio/libindi/libindi/CMakeLists.txt
r619 r642 1 1 cmake_minimum_required(VERSION 2.4.7) 2 PROJECT(libindi C CXX) 2 3 3 4 ################## INDI version ################################ 4 5 set(INDI_SOVERSION "0") 5 6 set(CMAKE_INDI_VERSION_MAJOR 0) 6 set(CMAKE_INDI_VERSION_MINOR 8)7 set(CMAKE_INDI_VERSION_MINOR 9) 7 8 set(CMAKE_INDI_VERSION_RELEASE 0) 8 9 set(CMAKE_INDI_VERSION_STRING "${CMAKE_INDI_VERSION_MAJOR}.${CMAKE_INDI_VERSION_MINOR}.${CMAKE_INDI_VERSION_RELEASE}") … … 13 14 set(BIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin") 14 15 set(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include") 15 16 MESSAGE( STATUS "BIN_INSTALL_DIR: " ${BIN_INSTALL_DIR} )17 16 18 17 ################## setup install directories ################################ … … 30 29 include (CheckIncludeFiles) 31 30 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) 31 FIND_PACKAGE(ZLIB REQUIRED) 32 FIND_PACKAGE(USB REQUIRED) 33 FIND_PACKAGE(CFITSIO REQUIRED) 44 34 45 35 if (NOT CFITSIO_FOUND OR CFITSIO_VERSION_MAJOR LESS 3) … … 48 38 49 39 macro_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 40 macro_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.") 52 41 53 42 macro_optional_find_package(Nova) 54 43 macro_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.")44 macro_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.") 56 45 57 46 check_include_files(linux/videodev2.h HAVE_LINUX_VIDEODEV2_H) … … 112 101 ${CMAKE_SOURCE_DIR}/libs/indibase/indifocuser.cpp 113 102 ${CMAKE_SOURCE_DIR}/libs/indibase/indiusbdevice.cpp 103 ${CMAKE_SOURCE_DIR}/libs/indibase/indiguiderinterface.cpp 104 ${CMAKE_SOURCE_DIR}/libs/indibase/indifilterinterface.cpp 105 114 106 ) 115 107 … … 121 113 set(indiserver_SRCS indiserver.c fq.c) 122 114 123 add_executable(indiserver ${indiserver_SRCS} 124 125 target_link_libraries(indiserver pthread)115 add_executable(indiserver ${indiserver_SRCS} ${liblilxml_SRCS}) 116 117 target_link_libraries(indiserver pthread) 126 118 127 119 if (NOVA_FOUND) … … 129 121 endif (NOVA_FOUND) 130 122 131 install(TARGETS indiserver RUNTIME DESTINATION bin 123 install(TARGETS indiserver RUNTIME DESTINATION bin) 132 124 133 125 ################################################# … … 146 138 endif(CFITSIO_FOUND) 147 139 148 install(TARGETS indi LIBRARY DESTINATION lib${LIB_POSTFIX})140 install(TARGETS indi LIBRARY DESTINATION ${LIB_DESTINATION}) 149 141 set_target_properties(indi PROPERTIES VERSION ${CMAKE_INDI_VERSION_STRING} SOVERSION ${INDI_SOVERSION}) 150 142 … … 154 146 ################################################## 155 147 add_library(indimain STATIC ${indimain_SRCS}) 156 install(TARGETS indimain ARCHIVE DESTINATION lib${LIB_POSTFIX})148 install(TARGETS indimain ARCHIVE DESTINATION ${LIB_DESTINATION}) 157 149 158 150 ################################################## … … 161 153 ################################################## 162 154 add_library(indidriver STATIC ${indimain_SRCS} ${indidriver_SRCS}) 163 install(TARGETS indidriver ARCHIVE DESTINATION lib${LIB_POSTFIX})155 install(TARGETS indidriver ARCHIVE DESTINATION ${LIB_DESTINATION}) 164 156 165 157 ################################################## … … 168 160 add_library(indiclient STATIC ${indiclient_SRCS}) 169 161 target_link_libraries(indiclient indi pthread) 170 install(TARGETS indiclient ARCHIVE DESTINATION lib${LIB_POSTFIX})162 install(TARGETS indiclient ARCHIVE DESTINATION ${LIB_DESTINATION}) 171 163 172 164 ##################################### … … 200 192 ${CMAKE_SOURCE_DIR}/drivers/telescope/lx200classic.cpp 201 193 ${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) 203 196 204 197 add_executable(indi_lx200generic ${lx200generic_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS}) … … 213 206 214 207 file(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 209 exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic \$ENV{DESTDIR}${BIN_INSTALL_DIR}/indi_lx200autostar)\n 210 exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic \$ENV{DESTDIR}${BIN_INSTALL_DIR}/indi_lx200_16)\n 211 exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic \$ENV{DESTDIR}${BIN_INSTALL_DIR}/indi_lx200gps)\n 212 exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic \$ENV{DESTDIR}${BIN_INSTALL_DIR}/indi_lx200ap)\n 213 exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic \$ENV{DESTDIR}${BIN_INSTALL_DIR}/indi_lx200fs2)\n 220 214 ") 221 215 set_target_properties(indi_lx200generic PROPERTIES POST_INSTALL_SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/make_lx200generic_symlink.cmake) … … 311 305 set(BAO_SRCS 312 306 ${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 316 314 ${CMAKE_SOURCE_DIR}/drivers/telescope/BAO.cpp 317 ${CMAKE_SOURCE_DIR}/drivers/telescope/exception.c318 ${CMAKE_SOURCE_DIR}/drivers/telescope/filetools.cpp319 315 ) 320 316 … … 329 325 330 326 install(TARGETS indi_BAO RUNTIME DESTINATION bin ) 331 332 327 ########### Syncscan ############### 333 328 set(synscan_SRCS … … 344 339 345 340 install(TARGETS indi_synscan RUNTIME DESTINATION bin ) 341 342 ########### Magellan I ############# 343 set(magellan_SRCS 344 ${indimain_SRCS} 345 ${CMAKE_SOURCE_DIR}/drivers/telescope/magellandriver.c 346 ${CMAKE_SOURCE_DIR}/drivers/telescope/magellan1.cpp ) 347 348 add_executable(indi_magellan1 ${magellan_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS}) 349 350 if (NOVA_FOUND) 351 target_link_libraries(indi_magellan1 ${NOVA_LIBRARIES}) 352 endif (NOVA_FOUND) 353 354 install(TARGETS indi_magellan1 RUNTIME DESTINATION bin ) 355 356 ########### IEQ45 ############# 357 set(ieq45_SRCS 358 ${indimain_SRCS} 359 ${CMAKE_SOURCE_DIR}/drivers/telescope/ieq45driver.c 360 ${CMAKE_SOURCE_DIR}/drivers/telescope/ieq45.cpp ) 361 362 add_executable(indi_ieq45 ${ieq45_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS}) 363 364 if (NOVA_FOUND) 365 target_link_libraries(indi_ieq45 ${NOVA_LIBRARIES}) 366 endif (NOVA_FOUND) 367 368 install(TARGETS indi_ieq45 RUNTIME DESTINATION bin ) 346 369 347 370 ########### Telescope Simulator ############## … … 361 384 install(TARGETS indi_simulator_telescope RUNTIME DESTINATION bin ) 362 385 386 ########### CCD Simulator ############## 387 if (CFITSIO_FOUND) 388 389 set(ccdsimulator_SRCS 390 ${indimain_SRCS} 391 ${CMAKE_SOURCE_DIR}/drivers/ccd/ccd_simulator.cpp 392 ) 393 394 add_executable(indi_simulator_ccd ${ccdsimulator_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS}) 395 396 target_link_libraries(indi_simulator_ccd indidriver ${CFITSIO_LIBRARIES} m z pthread) 397 398 if (NOVA_FOUND) 399 target_link_libraries(indi_simulator_ccd ${NOVA_LIBRARIES}) 400 endif (NOVA_FOUND) 401 402 install(TARGETS indi_simulator_ccd RUNTIME DESTINATION bin ) 403 404 endif (CFITSIO_FOUND) 405 406 363 407 ##################################### 364 408 ########## FOCUSER GROUP ############ 365 409 ##################################### 366 410 367 ########### CCD Simulator ##############368 if (CFITSIO_FOUND)369 370 set(ccdsimulator_SRCS371 ${indimain_SRCS}372 ${CMAKE_SOURCE_DIR}/drivers/ccd/ccd_simulator.cpp373 )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 392 411 ################################################################################# 393 412 … … 396 415 set(robofocus_SRCS 397 416 ${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 400 418 ) 401 419 402 420 add_executable(indi_robo_focus ${robofocus_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS}) 403 421 404 target_link_libraries(indi_robo_focus m)422 target_link_libraries(indi_robo_focus indidriver m z) 405 423 406 424 if (NOVA_FOUND) … … 428 446 429 447 file(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") 431 449 set_target_properties(indi_tcfs_focus PROPERTIES POST_INSTALL_SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/make_tcfs_symlink.cmake) 432 450 … … 741 759 ${CMAKE_SOURCE_DIR}/libs/indibase/indiccd.h ${CMAKE_SOURCE_DIR}/libs/indibase/indifilterwheel.h 742 760 ${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 745 764 DESTINATION ${INCLUDE_INSTALL_DIR}/libindi COMPONENT Devel) 746 765 -
BAORadio/libindi/libindi/ChangeLog
r504 r642 1 From 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 1 11 From 0.7.2 to 0.8 2 12 -
BAORadio/libindi/libindi/Doxyfile
r501 r642 6 6 DOXYFILE_ENCODING = UTF-8 7 7 PROJECT_NAME = "Instrument Neutral Distributed Interface INDI" 8 PROJECT_NUMBER = 0. 78 PROJECT_NUMBER = 0.9 9 9 OUTPUT_DIRECTORY = /home/jasem/Projects/doc 10 10 CREATE_SUBDIRS = NO -
BAORadio/libindi/libindi/INSTALL
r504 r642 1 INDI Library Setup 0. 8.01 INDI Library Setup 0.9.0 2 2 ======================== 3 3 … … 19 19 + libusb 20 20 + libnova >= 0.12.2 21 + libfli >= 1.722 21 + cfitsio >= 3.0 23 22 -
BAORadio/libindi/libindi/Indi_Stellarium/src/Makefile
r623 r642 54 54 55 55 clean: 56 rm *.o *.obj56 rm *.o TelescopeServerBAO 57 57 58 58 make.dep: -
BAORadio/libindi/libindi/README
r504 r642 1 libindi v0. 81 libindi v0.9 2 2 ============ 3 3 -
BAORadio/libindi/libindi/cmake_modules/FindAPOGEE.cmake
r490 r642 52 52 else (APOGEE_FOUND) 53 53 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") 55 55 endif (APOGEE_FIND_REQUIRED) 56 56 endif (APOGEE_FOUND) -
BAORadio/libindi/libindi/cmake_modules/FindINDI.cmake
r504 r642 60 60 ) 61 61 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") 67 73 68 74 … … 72 78 message(STATUS "INDI Include: ${INDI_INCLUDE_DIR}, INDI Data: ${INDI_DATA_DIR}") 73 79 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)78 80 endif (INDI_FOUND) 79 81 -
BAORadio/libindi/libindi/drivers.xml
r504 r642 1 1 <devGroup group="Telescopes"> 2 2 <device label="BAO" focal_length="" aperture=""> 3 3 <driver name="BAO">indi_BAO</driver> 4 4 <version>1.0</version> … … 108 108 <version>1.0</version> 109 109 </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> 110 118 <device label="Telescope Simulator" focal_length="" aperture=""> 111 119 <driver name="Telescope Simulator">indi_simulator_telescope</driver> … … 114 122 </devGroup> 115 123 <devGroup group="Focusers"> 116 <device label="Robo 117 <driver name="Robo focus">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> 119 127 </device> 120 128 <device label="Optec TCF-S"> … … 130 138 <device label="CCD Simulator"> 131 139 <driver name="CCD Simulator">indi_simulator_ccd</driver> 132 <version> 0.1</version>140 <version>1.0</version> 133 141 </device> 134 142 </devGroup> 135 143 <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>140 144 <device label="TruTech Wheel"> 141 145 <driver name="TruTech Wheel">indi_trutech_wheel</driver> … … 144 148 <device label="Filter Simulator"> 145 149 <driver name="Filter Simulator">indi_simulator_wheel</driver> 146 <version> 0.1</version>150 <version>1.0</version> 147 151 </device> 148 152 </devGroup> -
BAORadio/libindi/libindi/drivers/ccd/ccd_simulator.cpp
r504 r642 2 2 Copyright(c) 2010 Gerry Rozema. All rights reserved. 3 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. 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. 20 17 *******************************************************************************/ 21 18 #include "ccd_simulator.h" … … 84 81 void ISSnoopDevice (XMLEle *root) 85 82 { 86 INDI_UNUSED(root); 83 ISInit(); 84 ccdsim->ISSnoopDevice(root); 87 85 } 88 86 … … 125 123 TimeFactor=1; 126 124 125 SimulatorSettingsNV = new INumberVectorProperty; 126 TimeFactorSV = new ISwitchVectorProperty; 127 127 128 } 128 129 129 130 bool CCDSim::SetupParms() 130 131 { 132 int nbuf; 131 133 SetCCDParams(SimulatorSettingsN[0].value,SimulatorSettingsN[1].value,16,SimulatorSettingsN[2].value,SimulatorSettingsN[3].value); 132 134 // Kwiq … … 141 143 seeing=SimulatorSettingsN[9].value; // we get real fat stars in this one 142 144 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); 149 148 150 149 return true; … … 154 153 { 155 154 155 int nbuf; 156 156 SetupParms(); 157 157 158 if(HasGuideHead) { 158 if(HasGuideHead) 159 { 159 160 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); 163 163 } 164 164 … … 174 174 const char * CCDSim::getDefaultName() 175 175 { 176 //fprintf(stderr,"Arrived in getDefaultName and deviceName returns '%s'\n",deviceName());177 //if(strlen(deviceName())==0) {178 176 return (char *)"CCD Simulator"; 179 //} else {180 // char n[500];181 // strcpy(n,deviceName());182 // return n;183 //}184 177 } 185 178 … … 190 183 INDI::CCD::initProperties(); 191 184 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); 200 187 IUFillNumber(&SimulatorSettingsN[2],"SIM_XSIZE","CCD X Pixel Size","%4.2f",0,60,0,5.2); 201 188 IUFillNumber(&SimulatorSettingsN[3],"SIM_YSIZE","CCD Y Pixel Size","%4.2f",0,60,0,5.2); … … 209 196 IUFillNumber(&SimulatorSettingsN[11],"SIM_SKYGLOW","Sky Glow (magnitudes)","%4.1f",0,6000,0,19.5); 210 197 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 219 200 220 201 IUFillSwitch(&TimeFactorS[0],"1X","Actual Time",ISS_ON); … … 224 205 225 206 226 loadConfig();207 //loadConfig(); 227 208 228 209 return true; … … 238 219 defineNumber(SimulatorSettingsNV); 239 220 defineSwitch(TimeFactorSV); 240 defineText(TelescopeTV);241 221 //IDDefText(&ConfigFileTV, NULL); 242 222 //IDDefSwitch(&ConfigSaveRestoreSV, NULL); … … 257 237 bool CCDSim::Disconnect() 258 238 { 259 delete RawFrame;260 RawFrameSize=0;261 RawFrame=NULL;262 263 264 if(RawGuiderFrame != NULL) {265 delete RawGuiderFrame;266 RawGuideSize=0;267 }268 269 239 return true; 270 240 } … … 335 305 float timeleft; 336 306 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 337 315 if(timeleft < 1.0) 338 316 { … … 347 325 } 348 326 } 327 349 328 if(InGuideExposure) 350 329 { 351 330 float timeleft; 352 331 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 353 341 if(timeleft < 1.0) 354 342 { … … 390 378 unsigned short int val; 391 379 392 ptr=(unsigned short int *)RawFrame; 393 394 if(ShowStarField) { 380 ptr=(unsigned short int *) PrimaryCCD.getFrameBuffer(); 381 382 if(ShowStarField) 383 { 395 384 char gsccmd[250]; 396 385 FILE *pp; … … 423 412 424 413 // Start by clearing the frame buffer 425 memset( RawFrame,0,RawFrameSize);414 memset(PrimaryCCD.getFrameBuffer(),0,PrimaryCCD.getFrameBufferSize()); 426 415 427 416 … … 439 428 // no offset or rotation for and y axis means 440 429 pb=0.0; 441 pc= XRes/2/BinX;430 pc=PrimaryCCD.getXRes()/2/PrimaryCCD.getBinX(); 442 431 pd=0.0; 443 pf= YRes/2/BinY;432 pf=PrimaryCCD.getYRes()/2/PrimaryCCD.getBinY(); 444 433 // and we do a simple scale for x and y locations 445 434 // based on the focal length and pixel size 446 435 // focal length in mm, pixels in microns 447 pa=focallength/P ixelSizex*1000/BinX;448 pe=focallength/P ixelSizey*1000/BinY;436 pa=focallength/PrimaryCCD.getPixelSizeX()*1000/PrimaryCCD.getBinX(); 437 pe=focallength/PrimaryCCD.getPixelSizeY()*1000/PrimaryCCD.getBinY(); 449 438 450 439 //IDLog("Pixels are %4.2f %4.2f pa %6.4f pe %6.4f\n",PixelSizex,PixelSizey,pa,pe); … … 478 467 float radius; 479 468 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)); 481 470 // we have radius in arcseconds now 482 471 radius=radius/60; // convert to arcminutes … … 505 494 506 495 // 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) 508 497 { 509 498 //sprintf(gsccmd,"gsc -c %8.6f %+8.6f -r 120 -m 0 9.1",rad+PEOffset,Dec); … … 593 582 // fwhm equivalent to the full field of view 594 583 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)) 596 587 { 597 588 float skyflux; … … 599 590 // calculate flux from our zero point and gain values 600 591 glow=skyglow; 601 if( FrameType==FRAME_TYPE_FLAT)592 if(ftype==CCDChip::FLAT_FRAME) 602 593 { 603 594 // Assume flats are done with a diffuser … … 610 601 // ok, flux represents one second now 611 602 // scale up linearly for exposure time 612 skyflux=skyflux*ExposureRequest* BinX*BinY;603 skyflux=skyflux*ExposureRequest*PrimaryCCD.getBinX()*PrimaryCCD.getBinY(); 613 604 //IDLog("SkyFlux = %4.2f ExposureRequest %4.2f\n",skyflux,ExposureRequest); 614 605 615 606 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++) { 619 613 float dc; // distance from center 620 614 float fp; // flux this pixel; … … 622 616 float vig; 623 617 624 sx= XRes/2/BinX;618 sx=PrimaryCCD.getXRes()/2/PrimaryCCD.getBinX(); 625 619 sx=sx-x; 626 sy= YRes/2/BinY;620 sy=PrimaryCCD.getYRes()/2/PrimaryCCD.getBinY(); 627 621 sy=sy-y; 628 622 629 vig= XRes/BinX;623 vig=PrimaryCCD.getXRes()/PrimaryCCD.getBinX(); 630 624 vig=vig*ImageScalex; 631 625 // need to make this account for actual pixel size … … 654 648 655 649 // 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++) { 658 652 int noise; 659 653 … … 671 665 val=testvalue; 672 666 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++) 674 670 { 675 671 *ptr=val++; … … 686 682 unsigned char val; 687 683 688 ptr=(unsigned char *) RawGuiderFrame;684 ptr=(unsigned char *) GuideCCD.getFrameBuffer(); 689 685 testvalue++; 690 686 if(testvalue > 255) testvalue=0; 691 687 val=testvalue; 692 688 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 { 694 692 *ptr=val++; 695 693 ptr++; … … 708 706 float flux; 709 707 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())) 711 709 { 712 710 // this star is not on the ccd frame anyways … … 750 748 float fa; 751 749 fa=exp(-2.0*0.7*(dc*dc)/seeing/seeing); 752 fp=fa*flux* BinX*BinY;750 fp=fa*flux*PrimaryCCD.getBinX()*PrimaryCCD.getBinY(); 753 751 if(fp < 0) fp=0; 754 752 … … 773 771 int drew=0; 774 772 if(x >= 0) { 775 if(x < XRes/BinX) {773 if(x < PrimaryCCD.getXRes()/PrimaryCCD.getBinX()) { 776 774 if(y >= 0) { 777 if(y < YRes/BinY) {775 if(y < PrimaryCCD.getYRes()/PrimaryCCD.getBinY()) { 778 776 unsigned short *pt; 779 777 int newval; 780 778 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()); 783 781 pt+=x; 784 782 newval=pt[0]; … … 793 791 } 794 792 795 intCCDSim::GuideNorth(float v)793 bool CCDSim::GuideNorth(float v) 796 794 { 797 795 float c; … … 801 799 Dec=Dec+c; 802 800 803 return 0;804 } 805 intCCDSim::GuideSouth(float v)801 return true; 802 } 803 bool CCDSim::GuideSouth(float v) 806 804 { 807 805 float c; … … 811 809 Dec=Dec-c; 812 810 813 return 0;814 } 815 816 intCCDSim::GuideEast(float v)811 return true; 812 } 813 814 bool CCDSim::GuideEast(float v) 817 815 { 818 816 float c; … … 823 821 RA=RA-c; 824 822 825 return 0;826 } 827 intCCDSim::GuideWest(float v)823 return true; 824 } 825 bool CCDSim::GuideWest(float v) 828 826 { 829 827 float c; … … 834 832 RA=RA+c; 835 833 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 } 856 836 857 837 bool CCDSim::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) … … 859 839 // first check if it's for our device 860 840 //IDLog("INDI::CCD::ISNewNumber %s\n",name); 861 if(strcmp(dev,deviceName())==0) { 841 if(strcmp(dev,deviceName())==0) 842 { 862 843 // This is for our device 863 844 // Now lets see if it's something we process here … … 899 880 return INDI::CCD::ISNewNumber(dev,name,values,names,n); 900 881 } 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 process904 //IDLog("IndiTelescope got %d new text items name %s\n",n,name);905 // first check if it's for our device906 if(strcmp(dev,deviceName())==0) {907 // This is for our device908 // Now lets see if it's something we process here909 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 display916 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 it921 return true;922 }923 924 }925 926 return INDI::DefaultDriver::ISNewText(dev,name,texts,names,n);927 }928 882 929 883 -
BAORadio/libindi/libindi/drivers/ccd/ccd_simulator.h
r504 r642 2 2 Copyright(c) 2010 Gerry Rozema. All rights reserved. 3 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. 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. 20 17 *******************************************************************************/ 21 18 … … 65 62 bool AbortGuideFrame; 66 63 67 float RA; 68 float Dec; 64 69 65 float GuideRate; 70 66 … … 73 69 time_t RunStart; 74 70 75 // We are going to snoop these from a telescope76 INumberVectorProperty EqNV;77 INumber EqN[2];78 79 71 // And this lives in our simulator settings page 80 72 81 73 INumberVectorProperty *SimulatorSettingsNV; 82 74 INumber SimulatorSettingsN[13]; 83 84 ITextVectorProperty *TelescopeTV; // A text vector that stores the telescope we want to snoop85 IText TelescopeT[1];86 87 //ISwitch ConfigSaveRestoreS[2];88 //ISwitchVectorProperty ConfigSaveRestoreSV;89 75 90 76 ISwitch TimeFactorS[3]; … … 103 89 104 90 void ISGetProperties (const char *dev); 105 void ISSnoopDevice (XMLEle *root);106 107 91 108 92 … … 123 107 int AddToPixel(int,int,int); 124 108 125 intGuideNorth(float);126 intGuideSouth(float);127 intGuideEast(float);128 intGuideWest(float);109 bool GuideNorth(float); 110 bool GuideSouth(float); 111 bool GuideEast(float); 112 bool GuideWest(float); 129 113 130 114 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);132 115 virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n); 133 116 -
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 1 19 #include "filter_simulator.h" 2 20 … … 90 108 } 91 109 92 intFilterSim::SelectFilter(int f)110 bool FilterSim::SelectFilter(int f) 93 111 { 94 112 CurrentFilter=f; 95 113 SetTimer(500); 96 return 0;114 return true; 97 115 } 98 116 -
BAORadio/libindi/libindi/drivers/filter_wheel/filter_simulator.h
r504 r642 2 2 Copyright(c) 2010 Gerry Rozema. All rights reserved. 3 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. 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. 8 7 9 This program is distributed in the hope that it will be useful, but WITHOUT10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for12 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. 13 12 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. 20 17 *******************************************************************************/ 21 18 … … 37 34 bool Connect(); 38 35 bool Disconnect(); 39 intSelectFilter(int);36 bool SelectFilter(int); 40 37 void TimerHit(); 38 39 virtual bool SetFilterNames() { return false; } 40 virtual bool GetFilterNames(const char *deviceName, const char* groupName) { return false; } 41 41 42 42 43 }; -
BAORadio/libindi/libindi/drivers/focuser/tcfs.cpp
r504 r642 82 82 if(dev && strcmp (mydev, dev)) return; 83 83 ISInit(); 84 tcfs->ISNewSwitch( name, states, names, num);84 tcfs->ISNewSwitch(dev, name, states, names, num); 85 85 } 86 86 … … 89 89 if(dev && strcmp (mydev, dev)) return; 90 90 ISInit(); 91 tcfs->ISNewText( name, texts, names, num);91 tcfs->ISNewText(dev, name, texts, names, num); 92 92 } 93 93 … … 96 96 if(dev && strcmp (mydev, dev)) return; 97 97 ISInit(); 98 tcfs->ISNewNumber( name, values, names, num);98 tcfs->ISNewNumber(dev, name, values, names, num); 99 99 } 100 100 … … 239 239 if (tty_connect(tProp->tp[0].text, 19200, 8, 0, 1, &fd) != TTY_OK) 240 240 { 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); 243 242 return false; 244 243 } … … 252 251 if (!strcmp(response, "!")) 253 252 { 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."); 255 254 256 255 IUResetSwitch(FocusModeSP); … … 275 274 } 276 275 277 setConnected(false, IPS_ALERT, "Error connecting to TCF-S focuser...");276 IDMessage(deviceName(), "Error connecting to TCF-S focuser..."); 278 277 return false; 279 278 … … 306 305 ** 307 306 *****************************************************************/ 308 bool TCFS::ISNewNumber (const char * name, double values[], char *names[], int n)307 bool TCFS::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) 309 308 { 310 309 … … 317 316 { 318 317 resetProperties(); 319 IDMessage(device ID, "TCF-S is offline. Connect before issiung any commands.");318 IDMessage(deviceName(), "TCF-S is offline. Connect before issiung any commands."); 320 319 return false; 321 320 } … … 355 354 return true; 356 355 } 356 357 return DefaultDriver::ISNewNumber (dev, name, values, names, n); 357 358 358 359 } … … 362 363 ** 363 364 *****************************************************************/ 364 bool TCFS::ISNewText (const char * name, char *texts[], char *names[], int n)365 bool TCFS::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) 365 366 { 366 367 ITextVectorProperty * tProp = getText(name); … … 382 383 383 384 384 return false;385 return DefaultDriver::ISNewText(dev, name, texts, names, n); 385 386 386 387 } … … 390 391 ** 391 392 *****************************************************************/ 392 bool TCFS::ISNewSwitch (const char * name, ISState *states, char *names[], int n)393 bool TCFS::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) 393 394 { 394 395 395 396 ISwitch *current_active_switch = NULL, *target_active_switch = NULL; 396 397 // First process parent! 397 if (INDI::DefaultDriver::ISNewSwitch(device ID, name, states, names, n) == true)398 if (INDI::DefaultDriver::ISNewSwitch(deviceName(), name, states, names, n) == true) 398 399 return true; 399 400 … … 416 417 { 417 418 resetProperties(); 418 IDMessage(device ID, "TCF-S is offline. Connect before issiung any commands.");419 IDMessage(deviceName(), "TCF-S is offline. Connect before issiung any commands."); 419 420 return false; 420 421 } … … 663 664 664 665 665 return false;666 return DefaultDriver::ISNewSwitch(dev, name, states, names, n); 666 667 } 667 668 … … 930 931 const char * TCFS::getDefaultName() 931 932 { 932 return "TCFS";933 } 933 return mydev; 934 } -
BAORadio/libindi/libindi/drivers/focuser/tcfs.h
r504 r642 66 66 // Standard INDI interface fucntions 67 67 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); 71 71 72 72 -
BAORadio/libindi/libindi/drivers/telescope/BAO.cpp
r619 r642 11 11 12 12 #include "BAO.h" 13 #include "../communs/alt2motor.h" 13 14 14 15 … … 22 23 const char *OPTIONS_GROUP = "Options"; // Options Group 23 24 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 29 28 30 29 … … 34 33 35 34 35 36 36 /************************************************************************************** 37 37 ** Initialisation de la classe BAO 38 ** 38 39 ***************************************************************************************/ 39 40 … … 42 43 init_properties(); 43 44 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; 46 49 47 50 // 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; 70 107 71 108 72 109 // initialisation des sockets (Antennes) 73 110 74 111 for (int i=0; i<MAXHOSTNAME; i++) 75 112 { 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(); 81 120 } 82 121 83 122 // initialisations supplémentaires 84 123 85 124 InitAntennes(); 86 125 87 126 // Numéro de version 88 89 IDLog("In itilizing from BAO device...\n");90 IDLog("Driver Version: 2 011-12-02\n");127 128 IDLog("Indi server BAORadio...\n"); 129 IDLog("Driver Version: 23-02-2012\n"); 91 130 92 131 //connect_telescope(); … … 94 133 95 134 135 96 136 /************************************************************************************** 97 137 ** Destructeur 98 ** Lorsque l'on lance indi_BAO depuis indiserver dans un terminal99 ** Le destructeur ne semble jamais être atteint lorsque l'on sort... A vérifier100 ***************************************************************************************/ 138 ** 139 ***************************************************************************************/ 140 101 141 BAO::~BAO() 102 142 { 143 //On informe le thread que nous allons sortir 144 103 145 Exit = true; 146 147 // On lui laisse une seconde pour qu'il se termine 148 104 149 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 107 168 108 169 109 170 /************************************************************************************ 110 * Initialisation des paramÚtres des antennes111 * 171 ** Initialisation des paramÚtres des antennes 172 ** 112 173 ************************************************************************************/ 174 113 175 void BAO::InitAntennes() 114 176 { … … 121 183 Sockets[i].etape = 0; 122 184 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 133 196 134 197 135 198 /************************************************************************************** 136 199 ** 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 ** 137 202 ***************************************************************************************/ 138 203 … … 149 214 IUFillSwitchVector(&OnCoordSetSP, OnCoordSetS, NARRAY(OnCoordSetS), mydev, "ON_COORD_SET", "On Set", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE); 150 215 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 151 222 // Abort 152 223 IUFillSwitch(&AbortSlewS[0], "ABORT", "Abort", ISS_OFF); … … 171 242 IUFillNumberVector(&GeographicCoordsWNP, GeographicCoordsWN, NARRAY(GeographicCoordsWN), mydev, "GEOGRAPHIC_COORD" , "Geographic coords", OPTIONS_GROUP, IP_WO, 0, IPS_IDLE); 172 243 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 173 249 // 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.); 175 251 IUFillNumberVector(&ActualisationNP1, ActualisationN1, NARRAY(ActualisationN1), mydev, "DELAY1" , "", OPTIONS_GROUP, IP_WO, 0, IPS_IDLE); 176 252 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.); 178 254 IUFillNumberVector(&ActualisationNP2, ActualisationN2, NARRAY(ActualisationN2), mydev, "DELAY2" , "", OPTIONS_GROUP, IP_WO, 0, IPS_IDLE); 179 255 } … … 182 258 /************************************************************************************** 183 259 ** Initialisation de la boîte de dialogue INDI (suite) 260 ** Vider tous les vecteurs 261 ** 184 262 ***************************************************************************************/ 185 263 … … 195 273 IDDefNumber(&EquatorialCoordsWNP, NULL); 196 274 IDDefNumber(&GeographicCoordsWNP, NULL); 275 IDDefNumber(&PressionTempWNP, NULL); 197 276 IDDefSwitch(&OnCoordSetSP, NULL); 277 IDDefSwitch(&AlignmentSP, NULL); 198 278 IDDefSwitch(&AbortSlewSP, NULL); 199 279 IDDefSwitch(&ParkSP, NULL); … … 207 287 /************************************************************************************** 208 288 ** Initialisation des vecteurs INDI 289 ** ParamÚtres par défaut 290 ** 209 291 ***************************************************************************************/ 210 292 … … 213 295 ConnectSP.s = IPS_IDLE; 214 296 OnCoordSetSP.s = IPS_IDLE; 297 AlignmentSP.s = IPS_IDLE; 215 298 AbortSlewSP.s = IPS_IDLE; 216 299 ParkSP.s = IPS_IDLE; 217 300 ObjectTP.s = IPS_IDLE; 218 301 EquatorialCoordsWNP.s = IPS_IDLE; 302 PressionTempWNP.s = IPS_IDLE; 219 303 GeographicCoordsWNP.s = IPS_IDLE; 220 304 ActualisationNP1.s = IPS_IDLE; … … 222 306 223 307 IUResetSwitch(&OnCoordSetSP); 308 IUResetSwitch(&AlignmentSP); 224 309 IUResetSwitch(&AbortSlewSP); 225 310 IUResetSwitch(&ParkSP); 226 311 227 312 OnCoordSetS[0].s = ISS_ON; 313 AlignmentS[0].s = ISS_ON; 228 314 ConnectS[0].s = ISS_OFF; 229 315 ConnectS[1].s = ISS_ON; … … 231 317 IDSetSwitch(&ConnectSP, NULL); 232 318 IDSetSwitch(&OnCoordSetSP, NULL); 319 IDSetSwitch(&AlignmentSP, NULL); 233 320 IDSetSwitch(&AbortSlewSP, NULL); 234 321 IDSetSwitch(&ParkSP, NULL); 235 322 IDSetText(&ObjectTP, NULL); 236 323 IDSetNumber(&EquatorialCoordsWNP, NULL); 324 IDSetNumber(&PressionTempWNP, NULL); 237 325 IDSetNumber(&GeographicCoordsWNP, NULL); 238 326 IDSetNumber(&ActualisationNP1, NULL); … … 241 329 242 330 331 243 332 /************************************************************************************** 244 333 ** 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... 246 335 ** 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 ** 247 339 ***************************************************************************************/ 248 340 … … 275 367 276 368 369 277 370 /************************************************************************************** 278 371 ** En cas de changement d'une valeur numérique dans la boîte de dialogue Indi … … 285 378 286 379 // Ignore if not ours 380 287 381 if (strcmp (dev, mydev)) 288 382 return; 289 383 384 // Si pas de connexion -> on sort 385 290 386 if (is_connected() == false) 291 387 { 292 388 IDMessage(mydev, "Error ! BAO is offline. Please connect before issuing any commands."); 389 293 390 reset_all_properties(); 391 294 392 return; 295 393 } … … 299 397 // Geographic Coords 300 398 // =================================== 399 301 400 if (!strcmp (name, GeographicCoordsWNP.name)) 302 401 { 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 310 423 INumber *eqp = IUFindNumber (&GeographicCoordsWNP, names[i]); 424 311 425 if (eqp == &GeographicCoordsWN[0]) 312 426 { 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 313 431 Latitude = values[i]; 432 433 // On doit vérifier que la latitude est dans un intervalle correct 434 314 435 nset += Latitude >= -90.0 && Latitude <= 90.0; 436 437 // on convertit en radians 315 438 316 439 Latitude *= Pidiv180; … … 318 441 else if (eqp == &GeographicCoordsWN[1]) 319 442 { 443 // ici on a identifié une modification dans la rubrique longitude 444 320 445 Longitude = values[i]; 446 447 // dans l'intervalle ? 448 321 449 nset += Longitude >= 0.0 && Longitude <= 360.0; 450 451 // en radians 322 452 323 453 Longitude *= -Pidiv180; … … 332 462 //IDLog("Geographic : RA %5.2f - DEC %5.2f\n", Latitude, Longitude); 333 463 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 334 471 GeographicCoordsWNP.s = IPS_OK; 472 473 // pas de message d'erreur dans la boîte 474 335 475 IDSetNumber(&GeographicCoordsWNP, NULL); 336 476 } 337 477 else 338 478 { 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 339 485 GeographicCoordsWNP.s = IPS_ALERT; 486 487 // on affiche un message d'erreur 488 340 489 IDSetNumber(&GeographicCoordsWNP, "Latitude or Longitude missing or invalid"); 341 490 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... 345 499 346 500 DefinirLongitudeLatitude(Longitude, Latitude); … … 355 509 if (!strcmp (name, EquatorialCoordsWNP.name)) 356 510 { 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++) 361 518 { 362 519 INumber *eqp = IUFindNumber (&EquatorialCoordsWNP, names[i]); 520 363 521 if (eqp == &EquatorialCoordsWN[0]) 364 522 { 523 // on a compris que l'utilisateur avait changé l'ascension droite de l'objet 524 525 // on affecte la nouvelle valeur à newRA 526 365 527 newRA = values[i]; 528 529 // Est-ce que cette valeur est dans le bon intervalle ? 530 366 531 nset += newRA >= 0 && newRA <= 24.0; 367 532 } 368 533 else if (eqp == &EquatorialCoordsWN[1]) 369 534 { 535 //même chose pour la déclinaison 370 536 newDEC = values[i]; 537 371 538 nset += newDEC >= -90.0 && newDEC <= 90.0; 372 539 } … … 375 542 376 543 // si les coordonnées de l'objet sont correctes 544 377 545 if (nset == 2) 378 546 { … … 380 548 double targetAZ, targetAlt; 381 549 550 // On garde une trace des nouvelles coordonnées saisies par l'utilisateur 551 382 552 targetRA = newRA; 383 553 targetDEC = newDEC; 384 554 555 // on les affiches dans les logs 556 385 557 fs_sexa(RAStr, newRA, 2, 3600); 386 558 fs_sexa(DecStr, newDEC, 2, 3600); … … 392 564 393 565 ADDEC2Motor(newRA, newDEC); 566 567 // on déclenche le goto 394 568 395 569 if (process_coords() == false) 396 570 { 397 571 EquatorialCoordsWNP.s = IPS_ALERT; 572 398 573 IDSetNumber(&EquatorialCoordsWNP, NULL); 399 574 } … … 402 577 { 403 578 EquatorialCoordsWNP.s = IPS_ALERT; 579 404 580 IDSetNumber(&EquatorialCoordsWNP, "Error ! RA or Dec missing or invalid"); 405 581 } … … 407 583 return; 408 584 } 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 409 645 410 646 // =================================== … … 413 649 if (!strcmp (name, ActualisationNP1.name)) 414 650 { 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++) 419 660 { 420 661 INumber *eqp = IUFindNumber (&ActualisationNP1, names[i]); 662 421 663 if (eqp == &ActualisationN1[0]) 422 664 { 423 665 newAct1 = values[i]; 424 666 425 if ( newAct1 >= 0.0 && newAct1 <= 3600.0)667 if ( newAct1 >= 0.0 && newAct1 <= 3600.0 ) 426 668 { 427 ActualisationTM 1= newAct1;669 ActualisationTMTransit = newAct1; 428 670 429 671 ActualisationNP1.s = IPS_OK; 672 430 673 IDSetNumber(&ActualisationNP1, NULL); 431 674 } … … 433 676 { 434 677 ActualisationNP1.s = IPS_ALERT; 678 435 679 IDSetNumber(&ActualisationNP1, "Error ! Delay invalid"); 436 680 } … … 441 685 if (!strcmp (name, ActualisationNP2.name)) 442 686 { 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++) 447 690 { 448 691 INumber *eqp = IUFindNumber (&ActualisationNP2, names[i]); 692 449 693 if (eqp == &ActualisationN2[0]) 450 694 { 451 695 newAct2 = values[i]; 452 696 453 if ( newAct2 >= 0.0 && newAct2 <= 3600.0)697 if ( newAct2 >= 0.0 && newAct2 <= 3600.0 ) 454 698 { 455 ActualisationTM 2= newAct2;699 ActualisationTMTracking = newAct2; 456 700 457 701 ActualisationNP2.s = IPS_OK; 702 458 703 IDSetNumber(&ActualisationNP2, NULL); 459 704 } … … 469 714 470 715 716 471 717 /************************************************************************************** 472 718 ** L'utilisateur clique sur l'un des boutons de la boîte Indi 719 ** 473 720 ***************************************************************************************/ 474 721 … … 513 760 514 761 // =================================== 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 // =================================== 515 793 // Abort slew 516 794 // =================================== 517 795 if (!strcmp (name, AbortSlewSP.name)) 518 796 { 519 Abort =true;797 Abort = true; 520 798 521 799 IUResetSwitch(&AbortSlewSP); … … 568 846 ** l'utilisation d'un thread permet de contourner le problÚme de la fonction accept 569 847 ** qui est bloquante. 848 ** 570 849 ***************************************************************************************/ 571 850 … … 590 869 IDLog("\n");*/ 591 870 } 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 594 873 } 595 874 while (!Exit); … … 617 896 ** Le retour de la commande P est POSITION/valeur_az/valeur_alt/ 618 897 ** ExtractPosition retourne donc Valeur_az et Valeur_alt 898 ** 619 899 ***************************************************************************************/ 620 900 … … 633 913 if (pos != string::npos) 634 914 { 635 result->x = atol( str2.substr(0, pos).c_str());636 637 result->y = atol( str2.substr(pos + 1).c_str());638 639 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 } 642 922 643 923 IDLog((str +" failed !\n").c_str()); … … 649 929 650 930 /************************************************************************************ 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 ** 653 936 ************************************************************************************/ 654 937 … … 657 940 double targetAz; 658 941 double targetAlt; 942 double newRA2 = newRA * 15.0 * Pidiv180; 943 double newDEC2 = newDEC * Pidiv180; 659 944 char AzStr[32]; 660 945 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 773 950 for (int i=0; i<SocketsNumber; i++) 774 951 { 952 // On vérifie qu'elles sont encore connectées 953 775 954 if (Sockets[i].Connected) 776 955 { 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) 788 966 { 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 } 799 1007 } 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 } 804 1024 } 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()); 809 1080 } 810 1081 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 817 1152 818 1153 819 1154 /************************************************************************************ 820 * Retourne le nombre d'antennes connectées821 * 1155 * Retourne le nombre d'antennes actuellement connectées 1156 * 822 1157 ************************************************************************************/ 823 1158 … … 830 1165 return num; 831 1166 } 1167 832 1168 833 1169 … … 839 1175 void BAO::DeconnecterSocket(int num) 840 1176 { 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()); 842 1178 Sockets[num].new_sock.shutdown(); 843 1179 Sockets[num].Connected = false; 844 1180 Sockets[num].IP = ""; 845 1181 } 1182 1183 846 1184 847 1185 … … 877 1215 gettimeofday(&tv, &tz); 878 1216 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; 886 1224 887 1225 // On transmet la date et l'heure à la classe Astro … … 892 1230 893 1231 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 899 1251 900 1252 … … 946 1298 // on garde en stock la deuxiÚme partie de la trame 947 1299 // pour un traitement ultérieur 1300 948 1301 buffereponse = reponse.substr(pos + 1); 949 1302 950 1303 // Partie traitée 1304 951 1305 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()); 954 1310 955 1311 // On vérifie ici les acknowledges 1312 956 1313 if ((reponse.find("ACK") != string::npos) && (reponse.find("NACK") == string::npos)) 957 1314 { 958 1315 if (reponse.find("POSITION") != string::npos) 959 1316 { 960 Sockets[i].ack_pos =true;1317 Sockets[i].ack_pos = true; 961 1318 } 962 1319 else if (reponse.find("GOTO") != string::npos) 963 1320 { 964 Sockets[i].ack_goto =true;1321 Sockets[i].ack_goto = true; 965 1322 } 966 1323 else if (reponse.find("PARK") != string::npos) 967 1324 { 968 Sockets[i].ack_park =true;1325 Sockets[i].ack_park = true; 969 1326 } 970 1327 else if (reponse.find("ABORT")!= string::npos) 971 1328 { 972 Sockets[i].ack_abort =true;1329 Sockets[i].ack_abort = true; 973 1330 } 974 1331 } 975 1332 else 976 1333 { 977 // réponse à la requête POSITION1334 // Réponse à la requête POSITION 978 1335 979 1336 if (reponse.find("POSITION") != string::npos) 980 1337 { 1338 // Il y a une erreur signalée par le microcontroleur 1339 981 1340 if (reponse.find("NACK") != string::npos) 982 1341 { 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 984 1346 OnCoordSetSP.s = IPS_ALERT; 1347 985 1348 IDSetSwitch(&OnCoordSetSP, "ALERTE antenne %s : position de l antenne inconnue !\n", 986 1349 Sockets[i].IP.c_str()); 1350 1351 // La position de l'antenne st donc inconnue 1352 987 1353 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 989 1357 Sockets[i].Connected = false; 990 1358 } 991 1359 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 } 1006 1386 } 1007 1387 } … … 1013 1393 if (reponse.find("NACK") != string::npos) 1014 1394 { 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 1015 1398 ParkSP.s = IPS_ALERT; 1399 1400 // ... et on affiche un message d'erreur 1401 1016 1402 IDSetSwitch(&ParkSP, "ALERTE antenne %s : erreur PARK !\n", Sockets[i].IP.c_str()); 1017 1403 } 1018 1404 else if (Sockets[i].ack_park && reponse.find("OK")!=string::npos) 1019 1405 { 1406 // PARK ok ! 1407 1020 1408 ParkSP.s = IPS_OK; 1409 1021 1410 IDSetSwitch(&ParkSP, "Antenne %s : PARK OK\n", Sockets[i].IP.c_str()); 1022 1411 } … … 1029 1418 if (reponse.find("NACK") != string::npos) 1030 1419 { 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 1031 1423 AbortSlewSP.s = IPS_ALERT; 1424 1425 // ... et on affiche un message d'erreur 1426 1032 1427 IDSetSwitch(&AbortSlewSP, "ALERTE antenne %s : erreur ABORT !\n", Sockets[i].IP.c_str()); 1033 1428 } 1034 1429 else if (Sockets[i].ack_abort && reponse.find("OK")!=string::npos) 1035 1430 { 1431 // OK ! 1432 1036 1433 AbortSlewSP.s = IPS_OK; 1434 1037 1435 IDSetSwitch(&AbortSlewSP, "Antenne %s : ABORT OK\n", Sockets[i].IP.c_str()); 1038 1436 } 1039 1040 1437 } 1041 1438 … … 1046 1443 if (reponse.find("NACK") != string::npos) 1047 1444 { 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 1048 1448 OnCoordSetSP.s = IPS_ALERT; 1449 1450 // Message d'erreur 1451 1049 1452 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 1050 1456 DeconnecterSocket(i); 1051 1457 } … … 1061 1467 Sockets[i].GotoOk = true; 1062 1468 1469 // Voyant en vert dans la boîte Indi 1470 1471 OnCoordSetSP.s = IPS_OK; 1472 1063 1473 // Message pour l'utilisateur 1064 1065 OnCoordSetSP.s = IPS_OK; 1474 1066 1475 IDSetSwitch(&OnCoordSetSP, "Antenne %s : GOTO OK.\n", Sockets[i].IP.c_str()); 1067 1476 1068 1477 // 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; 1071 1481 1072 1482 for (int j=1; j<SocketsNumber; j++) 1073 1074 1483 { 1484 if (Sockets[j].Connected) 1075 1485 { 1076 1486 if (Sockets[j].GotoOk) num++; 1077 1487 } 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... 1079 1493 1080 1494 if ((num == AntennesConnectees()) && (num>0)) 1081 1495 { 1082 1496 // C'est bon ! Tout marche bien... 1083 1497 // On actualise l'AR et la dec dans la boîte de dialogue 1084 1498 … … 1086 1500 lastDEC = targetDEC; 1087 1501 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; 1091 1507 1092 1508 // Réinitialisation des paramÚtres des antennes en vue d'un prochain goto … … 1095 1511 1096 1512 // On dessine les voyants de la boîte de dialogue en vert 1513 1097 1514 OnCoordSetSP.s = IPS_OK; 1098 1515 EquatorialCoordsWNP.s = IPS_OK; … … 1100 1517 1101 1518 // 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 1104 1521 IDSetSwitch(&OnCoordSetSP, "GOTO OK !"); 1105 1106 UpdateGoto=true;1107 } 1522 1523 UpdatedGoto = true; 1524 } 1108 1525 } 1109 1526 } … … 1113 1530 // On passe à la trame suivante si memreponse n'est pas vide 1114 1531 1115 reponse =buffereponse;1116 pos =reponse.find("\n");1532 reponse = buffereponse; 1533 pos = reponse.find("\n"); 1117 1534 } 1118 1535 } 1119 1536 catch (SocketException& e) //Aïe 1120 1537 { 1538 // Une exception concerne le socket i 1539 1540 // On déconnecte l'antenne pour plus de sécurité 1541 1121 1542 DeconnecterSocket(i); 1122 1543 … … 1141 1562 // pour réaliser un goto 1142 1563 1143 ActualisationPosition= false;1564 RealisationGoto = false; 1144 1565 1145 1566 // On envoie l'ordre ABORT à toutes les antennes … … 1153 1574 } 1154 1575 1576 // Message à destination de l'utilisateur et des logs 1577 1155 1578 IDSetSwitch(&OnCoordSetSP, "ABORT OK !"); 1156 1579 … … 1161 1584 //Pour permettre de refaire un abort 1162 1585 1163 Abort =false;1586 Abort = false; 1164 1587 } 1165 1588 … … 1176 1599 // pour réaliser un goto 1177 1600 1178 ActualisationPosition= false;1601 RealisationGoto = false; 1179 1602 1180 1603 // On envoie l'ordre PARK à toutes les antennes … … 1196 1619 //Pour permettre de refaire un park 1197 1620 1198 Park =false;1621 Park = false; 1199 1622 } 1200 1623 … … 1203 1626 // Gestion du suivi 1204 1627 1205 if ((Suivi) && (Update Goto))1628 if ((Suivi) && (UpdatedGoto)) 1206 1629 { 1207 1630 // Délais entre deux actualisations 1208 1631 1209 double delai =ActualisationTM1 / 3600.0 / 24.0; // Actualisation toutes les 15 minutes en mode transit1210 1211 if (TrackingMode ==2) delai=ActualisationTM2 / 3600.0 / 24.0; //et 5 secs en mode tracking1632 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) 1212 1635 1213 1636 … … 1216 1639 if (GetJJ() - JJAnc > delai) 1217 1640 { 1218 UpdateGoto = false; 1641 // Cette variable vaudra true lorsque le goto aura été réalisé 1642 1643 UpdatedGoto = false; 1219 1644 1220 1645 // Conversion des coordonnées en pas moteur … … 1226 1651 InitAntennes(); 1227 1652 1228 ActualisationPosition = true; 1653 // On lance le processus d'actualisation du goto 1654 1655 RealisationGoto = true; 1229 1656 1230 1657 // On sauvegarde la date … … 1243 1670 if (Suivi) IDLog("Arrêt du suivi !"); 1244 1671 1245 ActualisationPosition=false;1672 RealisationGoto=false; 1246 1673 1247 1674 Suivi=false; … … 1254 1681 1255 1682 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) 1260 1692 { 1261 1693 for (int i=1; i<SocketsNumber; i++) 1262 1694 { 1695 // On ne parle qu'aux antennes connectées 1696 1263 1697 if (Sockets[i].Connected) 1264 1698 { 1699 // En fonction de l'étage de la réalisation d'un goto par l'antenne i 1700 1265 1701 switch (Sockets[i].etape) 1266 1702 { 1267 1703 1268 // Envoi de la commande POS1704 // Envoi de la commande POS 1269 1705 1270 1706 case 0 : 1271 1707 { 1708 // On doit intialiser l'acknowledge à false 1709 1272 1710 Sockets[i].ack_pos = false; 1711 1712 // et considérer que la position de l'antenne n'est pas valide 1713 1273 1714 Sockets[i].PosValides = false; 1274 1715 1716 // avant d'envoyer l'ordre POSITION 1717 1275 1718 if (!POSITION(i)) Sockets[i].sendalertes++; 1719 1720 // On passe à l'étage suivante 1276 1721 1277 1722 Sockets[i].etape++; … … 1286 1731 if (Sockets[i].ack_pos) 1287 1732 { 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 1289 1736 Sockets[i].AttenteExecution = 0; 1737 1738 // Pas d'anomalie à consigner 1290 1739 Sockets[i].AnomaliesExecution = 0; 1740 1741 // On passe à l'étape suivante 1291 1742 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--; 1294 1746 } 1295 1747 else 1296 1748 { 1297 // on réitÚre l'ordre précédent si rien ne se passe1749 // On réitÚre l'ordre précédent si rien ne se passe 1298 1750 1299 1751 // On garde une trace de l'anomalie 1752 1300 1753 Sockets[i].AttenteExecution++; 1301 1754 1302 1755 if (Sockets[i].AttenteExecution > MAXATTENTE) 1303 1756 { 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 ? 1305 1759 Sockets[i].etape = 0; 1306 1760 Sockets[i].AttenteExecution = 0; 1761 1762 // Pas de réponse. On consigne une erreur grave 1307 1763 Sockets[i].AnomaliesExecution++; 1308 1764 } 1309 1765 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 1311 1768 if (Sockets[i].AnomaliesExecution > MAXANOMALIES) 1312 1769 { 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 1314 1775 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()); 1776 Deconnexion de l antenne.", Sockets[i].IP.c_str()); 1777 1778 // On déconnecte l'antenne 1316 1779 DeconnecterSocket(i); 1317 1780 } … … 1327 1790 if (Sockets[i].PosValides) 1328 1791 { 1792 // Tout vas bien 1793 // On ne consigne aucune anomalie 1329 1794 Sockets[i].AttenteExecution = 0; 1330 1795 Sockets[i].AnomaliesExecution = 0; 1331 Sockets[i].etape++; // on passe à l'étape suivante 1796 1797 //On passe à l'étape suivante 1798 Sockets[i].etape++; 1332 1799 } 1333 1800 else 1334 1801 { 1335 1802 // on réitÚre l'ordre précédent si rien ne se passe 1803 1336 1804 Sockets[i].AttenteExecution++; 1337 1805 1338 1806 if (Sockets[i].AttenteExecution > MAXATTENTE) 1339 1807 { 1340 // on attend encore la réponse posvalides 1808 // on attend encore la réponse posvalides 1809 1341 1810 Sockets[i].etape = 2; 1342 1811 Sockets[i].AttenteExecution = 0; 1812 1813 // On consigne une erreur grave. L'antenne tarde à répondre 1343 1814 Sockets[i].AnomaliesExecution++; 1344 1815 } 1345 1816 1817 // Aucune réponse de l'antenne depuis plusieurs minutes 1818 // On la déconnecte 1346 1819 if (Sockets[i].AnomaliesExecution > MAXANOMALIES) 1347 1820 { 1348 OnCoordSetSP.s = IPS_ALERT; 1821 // Voyant en rouge 1822 1823 OnCoordSetSP.s = IPS_ALERT; 1824 1825 //Message d'erreur 1349 1826 IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : la position retournee n est pas valide. \ 1350 Deconnexion de l antenne.", Sockets[i].IP.c_str()); 1827 Deconnexion de l antenne.", Sockets[i].IP.c_str()); 1828 1829 //Déconnexion de l'antenne 1351 1830 DeconnecterSocket(i); 1352 1831 } … … 1354 1833 } 1355 1834 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... 1356 1841 1357 1842 … … 1373 1858 if (Sockets[i].AttenteExecution > MAXATTENTE) 1374 1859 { 1375 // On prolonge l'attente 1860 // On prolonge l'attente pour recevoir l'acknowledge du goto 1376 1861 Sockets[i].etape = 4; 1377 1862 Sockets[i].AttenteExecution = 0; … … 1381 1866 if (Sockets[i].AnomaliesExecution > MAXANOMALIES) 1382 1867 { 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 1386 1872 DeconnecterSocket(i); 1387 1873 } … … 1397 1883 if (Sockets[i].GotoOk) 1398 1884 { 1885 // On a bien reçu Goto Ok pour l'antenne i ! 1886 1399 1887 Sockets[i].AttenteExecution = 0; 1400 1888 Sockets[i].AnomaliesExecution = 0; 1889 1890 //On passe à l'étape suivante 1401 1891 Sockets[i].etape++; 1402 1892 } … … 1408 1898 if (Sockets[i].AttenteExecution > MAXATTENTE) 1409 1899 { 1410 // On prolonge l'attente 1411 1900 // On prolonge l'attente afin de recevoit un GOTO OK 1901 1412 1902 Sockets[i].etape = 5; 1413 1903 Sockets[i].AttenteExecution = 0; … … 1415 1905 } 1416 1906 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 1418 1908 if (Sockets[i].AnomaliesExecution > MAXANOMALIESGOTO) 1419 1909 { 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 1423 1917 DeconnecterSocket(i); 1424 1918 } … … 1433 1927 1434 1928 /////////////////////////////////////// 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; 1438 1938 1439 1939 for (int i=1; i<SocketsNumber; i++) 1440 1940 { 1941 // Uniquement les antennes connectées 1942 1441 1943 if (Sockets[i].Connected) 1442 1944 { 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 1445 1946 } 1446 1947 } 1948 1949 // Toutes les antennes connectées sont prêtes à recevoir l'ordre goto 1447 1950 1448 1951 if ((num == AntennesConnectees()) && (num>0)) … … 1452 1955 if (Sockets[i].Connected) 1453 1956 { 1957 // On envoie l'ordre 1958 1454 1959 Sockets[i].ack_goto = false; 1455 1960 Sockets[i].AttenteExecution = 0; 1456 1961 Sockets[i].AnomaliesExecution = 0; 1457 1962 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++; 1459 1964 1460 1965 Sockets[i].etape++; … … 1464 1969 1465 1970 /////////////////////////////////////// 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 1467 1974 1468 1975 for (int i=1; i<SocketsNumber; i++) … … 1472 1979 if (Sockets[i].sendalertes > 0) 1473 1980 { 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 1475 1987 IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : deconnexion de l antenne.", Sockets[i].IP.c_str()); 1988 1989 // Déconnexion antenne 1476 1990 1477 1991 DeconnecterSocket(i); … … 1480 1994 } 1481 1995 } 1482 1996 1483 1997 //incrémentation du compteur 1998 1484 1999 compt++; 1485 2000 } … … 1511 2026 InitAntennes(); 1512 2027 2028 // On garde la trace du début du Goto pour enchainer les actualisations 2029 1513 2030 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é 1516 2037 1517 2038 TrackingMode = 1; 1518 2039 2040 // On suit un objet 2041 1519 2042 Suivi = true; 1520 2043 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; 1524 2051 1525 2052 break; … … 1539 2066 InitAntennes(); 1540 2067 1541 JJAnc =GetJJ();1542 1543 2068 JJAnc = GetJJ(); 2069 2070 ADDEC2Motor(targetRA, targetDEC); 1544 2071 1545 2072 TrackingMode = 2; … … 1547 2074 Suivi = true; 1548 2075 1549 Update Goto = false;1550 1551 ActualisationPosition = true;2076 UpdatedGoto = false; 2077 2078 RealisationGoto = true; 1552 2079 1553 2080 break; … … 1581 2108 1582 2109 // 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 1585 2115 1586 2116 if (pthread_create (&th1, NULL, (void*(*)(void*))LancementThread, this) < 0) … … 1592 2122 1593 2123 case ISS_OFF: 1594 1595 // On sort du thread1596 1597 Exit = true;1598 sleep(1);1599 pthread_join (th1, NULL);1600 InitThreadOK = false;1601 2124 1602 2125 // Etat des voyants … … 1621 2144 SocketsNumber = 1; 1622 2145 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 1623 2168 break; 1624 2169 } … … 1630 2175 /************************************************************************************** 1631 2176 ** Envoie une commande sur le socket numsocket 2177 ** 1632 2178 ***************************************************************************************/ 1633 2179 … … 1639 2185 { 1640 2186 sprintf(chaine, "%s%s\n", Commande, Params); 1641 1642 1643 1644 2187 2188 Sockets[numsocket].new_sock << chaine; 2189 2190 IDLog("Commande envoyee a %s: %s", Sockets[numsocket].IP.c_str(), chaine); 1645 2191 } 1646 2192 catch (SocketException& e) 1647 2193 { 2194 // Consignation d'une anomalie sur le socket 2195 1648 2196 DeconnecterSocket(numsocket); 1649 2197 … … 1661 2209 /************************************************************************************** 1662 2210 ** Commande POSITION 2211 ** 1663 2212 ***************************************************************************************/ 1664 2213 … … 1670 2219 /************************************************************************************** 1671 2220 ** Commande PARK 2221 ** 1672 2222 ***************************************************************************************/ 1673 2223 … … 1679 2229 /************************************************************************************** 1680 2230 ** Commande ABORT 2231 ** 1681 2232 ***************************************************************************************/ 1682 2233 … … 1689 2240 /************************************************************************************** 1690 2241 ** Commande GOTO 2242 ** 1691 2243 ***************************************************************************************/ 1692 2244 … … 1700 2252 sensAz = 1; 1701 2253 2254 // gestion des signes des deltas 2255 1702 2256 if ( deltaAz < 0 ) 1703 2257 { … … 1713 2267 1714 2268 // 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 alors2269 // 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 1718 2272 // on fait le trajet dans le sens inverse pour aller plus vite 1719 2273 … … 1730 2284 { 1731 2285 deltaAz = NBREPASCODEURSAZ - deltaAz; 2286 1732 2287 sensAz = 1 - sensAz; 1733 2288 } … … 1735 2290 //on envoie les coordonnées au driver 1736 2291 1737 if (sensAz == 1 ) sensAz='f'; elsesensAz='b';1738 1739 if (sensAlt == 1 ) sensAlt='f'; elsesensAlt='b';2292 (sensAz == 1 ) ? sensAz='f' : sensAz='b'; 2293 2294 (sensAlt == 1 ) ? sensAlt='f': sensAlt='b'; 1740 2295 1741 2296 sprintf(Params, "%c%04i%c%04i", sensAz, deltaAz, sensAlt, deltaAlt); … … 1838 2393 1839 2394 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 else1860 IDSetSwitch (&OnCoordSetSP, "Slew failed.");1861 }1862 2395 1863 2396 /************************************************************************************** … … 1929 2462 1930 2463 2464 -
BAORadio/libindi/libindi/drivers/telescope/BAO.h
r619 r642 23 23 #include <fstream> 24 24 25 #include <termios.h> 26 #include <unistd.h> 27 25 28 #include <config.h> 26 27 29 #include "indicom.h" 28 29 #include "Socket.h"30 30 #include "indidevapi.h" 31 31 #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 45 39 46 40 using namespace std; 41 47 42 48 43 struct Position … … 52 47 }; 53 48 49 54 50 struct DefSocket 55 51 { 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 77 74 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 81 ServerSocket server( 8000 ); 83 82 84 83 class BAO : public Astro … … 88 87 ~BAO(); 89 88 89 /*******************************************************/ 90 /* Gestion de l'interface intégrée dans KStars 91 ********************************************************/ 92 90 93 void ISGetProperties (const char *dev); 91 94 void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n); … … 94 97 void ISPoll (); 95 98 99 /*******************************************************/ 100 /* Gestion des threads 101 ********************************************************/ 102 96 103 void *pThreadSocket (); 97 104 void *pThreadExit (); 98 105 106 /*******************************************************/ 107 /* Les commandes 108 ********************************************************/ 109 99 110 bool COMMANDE(int numsocket, char* Commande, char* Params); 100 111 bool ExtractPosition(string str, Position *result); 101 102 void connection_lost();103 void connection_resumed();104 105 112 bool STATUS(int numsocket); 106 113 bool POSITION(int numsocket); … … 108 115 bool PARK(int numsocket); 109 116 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); 111 125 int AntennesConnectees(); 112 126 void DeconnecterSocket(int num); 113 127 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 124 129 125 130 /*******************************************************/ … … 127 132 ********************************************************/ 128 133 bool process_coords(); 129 int get_switch_index(ISwitchVectorProperty *sp); 134 int get_switch_index(ISwitchVectorProperty *sp); 135 void ADDEC2Motor(double newRA, double newDEC); 130 136 131 137 /*******************************************************/ … … 137 143 /* Error handling routines 138 144 ********************************************************/ 139 void slew_error(int slewCode);140 145 void reset_all_properties(); 141 146 void handle_error(INumberVectorProperty *nvp, int err, const char *msg); 142 147 void correct_fault(); 143 148 void connection_lost(); 149 void connection_resumed(); 144 150 145 151 … … 147 153 148 154 enum BAO_STATUS { BAO_TRANSIT, BAO_TRACKING, BAO_PARK }; 155 156 // ParamÚtres par défaut d'un pilote indi 149 157 150 158 /* Switches */ 151 159 ISwitch ConnectS[2]; 152 160 ISwitch OnCoordSetS[2]; 161 ISwitch AlignmentS[3]; 153 162 ISwitch AbortSlewS[1]; 154 163 ISwitch ParkS[1]; … … 159 168 160 169 /* Numbers */ 161 //INumber EquatorialCoordsRN[2];162 170 INumber EquatorialCoordsWN[2]; 163 171 INumber GeographicCoordsWN[2]; 172 INumber PressionTempWN[2]; 164 173 INumber ActualisationN1[1]; 165 174 INumber ActualisationN2[1]; 166 167 //INumber SlewAccuracyN[2];168 //INumber TrackAccuracyN[2];169 175 170 176 /* Switch Vectors */ 171 177 ISwitchVectorProperty ConnectSP; 172 178 ISwitchVectorProperty OnCoordSetSP; 179 ISwitchVectorProperty AlignmentSP; 173 180 ISwitchVectorProperty AbortSlewSP; 174 181 ISwitchVectorProperty ParkSP; 175 182 176 183 /* Number Vectors */ 177 //INumberVectorProperty EquatorialCoordsRNP;178 184 INumberVectorProperty EquatorialCoordsWNP; 179 185 INumberVectorProperty GeographicCoordsWNP; 180 //INumberVectorProperty SlewAccuracyNP; 181 //INumberVectorProperty TrackAccuracyNP; 186 INumberVectorProperty PressionTempWNP; 182 187 INumberVectorProperty ActualisationNP1; 183 188 INumberVectorProperty ActualisationNP2; … … 191 196 192 197 protected: 198 193 199 int SocketsNumber; // nbre de sockets utilisés pour connecter les antennes 194 bool InitThreadOK; // Le thread est bien actif195 DefSocket Sockets[MAXHOSTNAME + 1]; // Etat dechaque socket. Un socket permet la communication avec une antenne200 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 196 202 pthread_t th1; // le pointeur du thread 197 203 198 204 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 201 207 double JJAnc; // Sauvegarde du jour julien lors de la derniÚre actualisation de la position (fct Goto) 202 double ActualisationTM 1; // Délais entre deux actualisations dans les modes transit et tracking203 double ActualisationTM 2;208 double ActualisationTMTransit; // Délai entre deux actualisations dans les modes transit 209 double ActualisationTMTracking; // " " " tracking 204 210 double Longitude; // Longitude et latitude du lieu d'observation 205 211 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 207 216 bool Abort; // Annulation du mouvement en cours 208 217 bool Park; // On place les antennes dans une position de repos 209 bool Suivi; // Suivi d'un objet en cours...210 bool Update Goto; // On peut exécuter un Goto218 bool Suivi; // Est-ce que les antennes suivent actuellement un objet ? 219 bool UpdatedGoto; // On peut exécuter un Goto 211 220 bool Exit; // On ferme le driver 212 221 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 218 225 }; 219 226 -
BAORadio/libindi/libindi/drivers/telescope/celestrongps.cpp
r490 r642 525 525 526 526 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); 530 531 531 532 // Previosuly active switch clicked again, so let's stop. … … 569 570 570 571 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); 574 576 575 577 // Previosuly active switch clicked again, so let's stop. -
BAORadio/libindi/libindi/drivers/telescope/celestronprotocol.c
r490 r642 286 286 { 287 287 slewCmd[2] = 0x10; 288 slewCmd[3] = 0x2 4;288 slewCmd[3] = 0x25; 289 289 } 290 290 else if(direction == SOUTH) 291 291 { 292 292 slewCmd[2] = 0x11; 293 slewCmd[3] = 0x2 4;293 slewCmd[3] = 0x25; 294 294 } 295 295 else if(direction == WEST) -
BAORadio/libindi/libindi/drivers/telescope/lx200driver.c
r490 r642 88 88 int setCommandXYZ(int fd, int x, int y, int z, const char *cmd); 89 89 /* Common routine for Set commands */ 90 int setStandardProcedure(int fd, c har * writeData);90 int setStandardProcedure(int fd, const char * writeData); 91 91 /* Set Slew Mode */ 92 92 int setSlewMode(int fd, int slewMode); … … 220 220 /*if ( (read_ret = portRead(temp_string, -1, LX200_TIMEOUT)) < 1) 221 221 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 224 228 temp_string[nbytes_read - 1] = '\0'; 225 229 … … 251 255 return error_type; 252 256 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; 254 261 255 262 temp_string[nbytes_read - 1] = '\0'; … … 685 692 **********************************************************************/ 686 693 687 int setStandardProcedure(int fd, c har * data)694 int setStandardProcedure(int fd, const char * data) 688 695 { 689 696 char bool_return[2]; -
BAORadio/libindi/libindi/drivers/telescope/lx200driver.h
r490 r642 174 174 int setCommandXYZ(int fd, int x, int y, int z, const char *cmd); 175 175 /* Common routine for Set commands */ 176 int setStandardProcedure(int fd, c har * writeData);176 int setStandardProcedure(int fd, const char * writeData); 177 177 /* Set Slew Mode */ 178 178 int setSlewMode(int fd, int slewMode); -
BAORadio/libindi/libindi/drivers/telescope/lx200generic.cpp
r504 r642 33 33 #include "lx200ap.h" 34 34 #include "lx200classic.h" 35 #include "lx200fs2.h" 35 36 36 37 #include <config.h> … … 331 332 changeLX200ClassicDeviceName(newName); 332 333 changeLX200GPSDeviceName(newName); 334 changeLX200FS2DeviceName(newName); 333 335 } 334 336 … … 464 466 465 467 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 466 489 } 467 490 // be nice and give them a generic device -
BAORadio/libindi/libindi/drivers/telescope/lx200generic.h
r490 r642 45 45 int checkPower(ISwitchVectorProperty *sp); 46 46 int checkPower(ITextVectorProperty *tp); 47 v oid handleError(ISwitchVectorProperty *svp, int err, const char *msg);48 v oid handleError(INumberVectorProperty *nvp, int err, const char *msg);49 v oid 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); 50 50 bool isTelescopeOn(void); 51 v oid connectTelescope();51 virtual void connectTelescope(); 52 52 void slewError(int slewCode); 53 53 void getAlignment(); … … 80 80 int currentSet; 81 81 int lastSet; 82 83 82 84 83 }; -
BAORadio/libindi/libindi/drivers/telescope/synscanmount.cpp
r504 r642 2 2 Copyright(c) 2010 Gerry Rozema. All rights reserved. 3 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. 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. 20 17 *******************************************************************************/ 18 21 19 #include "synscanmount.h" 22 20 #include "libs/indicom.h" … … 39 37 void ISPoll(void *p); 40 38 39 #define isDebug() true 41 40 42 41 void ISInit() … … 110 109 bool SynscanMount::initProperties() 111 110 { 112 if (isDebug())111 //if (isDebug()) 113 112 IDLog("Synscan::init_properties\n"); 114 113 … … 120 119 void SynscanMount::ISGetProperties (const char *dev) 121 120 { 122 if (isDebug())121 //if (isDebug()) 123 122 IDLog("Enter SynscanMount::ISGetProperties %s\n",dev); 124 123 … … 139 138 int n1,n2; 140 139 141 //IDLog(" Read Status\n");140 //IDLog("SynScan Read Status\n"); 142 141 //tty_write(PortFD,(unsigned char *)"Ka",2, &bytesWritten); // test for an echo 143 142 … … 147 146 { 148 147 // this is not a correct echo 149 if (isDebug())148 //if (isDebug()) 150 149 IDLog("ReadStatus Echo Fail\n"); 151 150 IDMessage(deviceName(),"Mount Not Responding"); … … 192 191 tty_write(PortFD,"e",1, &bytesWritten); 193 192 numread=tty_read(PortFD,str,18,1, &bytesRead); 194 if (numread!=18) 193 if (bytesRead!=18) 194 //if(str[17] != '#') 195 195 { 196 196 IDLog("read status bytes didn't get a full read\n"); … … 230 230 TrackState=SCOPE_SLEWING; 231 231 numread=tty_read(PortFD,str,1,60, &bytesRead); 232 if ( numread!=1||str[0]!='#')232 if (bytesRead!=1||str[0]!='#') 233 233 { 234 234 if (isDebug()) … … 258 258 tty_write(PortFD,"T0",2, &bytesWritten); 259 259 numread=tty_read(PortFD,str,1,60, &bytesRead); 260 if ( numread!=1||str[0]!='#')260 if (bytesRead!=1||str[0]!='#') 261 261 { 262 262 if (isDebug()) … … 268 268 tty_write(PortFD,"B0000,4000",10, &bytesWritten); 269 269 numread=tty_read(PortFD,str,1,60, &bytesRead); 270 if ( numread!=1||str[0]!='#')270 if (bytesRead!=1||str[0]!='#') 271 271 { 272 272 if (isDebug()) -
BAORadio/libindi/libindi/drivers/telescope/synscanmount.h
r504 r642 2 2 Copyright(c) 2010 Gerry Rozema. All rights reserved. 3 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. 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. 8 7 9 This program is distributed in the hope that it will be useful, but WITHOUT10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for12 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. 13 12 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. 20 17 *******************************************************************************/ 21 18 … … 39 36 const char *getDefaultName(); 40 37 38 //virtual bool Connect() {return true;} 41 39 bool ReadScopeStatus(); 42 40 bool Goto(double,double); -
BAORadio/libindi/libindi/drivers/telescope/telescope_simulator.cpp
r504 r642 13 13 std::auto_ptr<ScopeSim> telescope_sim(0); 14 14 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 16 24 #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 18 33 19 34 … … 80 95 currentDEC=15; 81 96 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) ); 82 108 } 83 109 … … 90 116 { 91 117 return (char *)"Telescope Simulator"; 118 } 119 120 bool 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 161 void 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 179 bool 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 206 bool 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; 92 218 } 93 219 … … 106 232 static struct timeval ltv; 107 233 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]; 110 238 111 239 … … 118 246 dt = tv.tv_sec - ltv.tv_sec + (tv.tv_usec - ltv.tv_usec)/1e6; 119 247 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 } 121 290 122 291 /* Process per current state. We check the state of EQUATORIAL_EOD_COORDS_REQUEST and act acoordingly */ 123 292 switch (TrackState) 124 293 { 294 case SCOPE_IDLE: 295 EqNV->s = IPS_IDLE; 296 break; 125 297 case SCOPE_SLEWING: 126 298 case SCOPE_PARKING: … … 130 302 dx = targetRA - currentRA; 131 303 132 if (fabs(dx) <= da)304 if (fabs(dx)*15. <= da_ra) 133 305 { 134 306 currentRA = targetRA; … … 136 308 } 137 309 else if (dx > 0) 138 currentRA += da /15.;310 currentRA += da_ra/15.; 139 311 else 140 currentRA -= da /15.;141 142 143 d x= targetDEC - currentDEC;144 if (fabs(d x) <= da)312 currentRA -= da_ra/15.; 313 314 315 dy = targetDEC - currentDEC; 316 if (fabs(dy) <= da_dec) 145 317 { 146 318 currentDEC = targetDEC; 147 319 nlocked++; 148 320 } 149 else if (d x> 0)150 currentDEC += da ;321 else if (dy > 0) 322 currentDEC += da_dec; 151 323 else 152 currentDEC -= da; 324 currentDEC -= da_dec; 325 326 EqNV->s = IPS_BUSY; 153 327 154 328 if (nlocked == 2) 155 329 { 156 //eqNP.s = IPS_OK;157 //eqNPR.s = IPS_OK;158 //IDSetNumber(&eqNP, NULL);159 //IDSetNumber(&eqNPR, "Now tracking");160 330 if (TrackState == SCOPE_SLEWING) 161 331 { 332 333 // Initially no PEC in both axis. 334 EqPECN[0].value = currentRA; 335 EqPECN[1].value = currentDEC; 336 337 IDSetNumber(EqPECNV, NULL); 338 162 339 TrackState = SCOPE_TRACKING; 340 341 EqNV->s = IPS_OK; 163 342 IDMessage(deviceName(), "Telescope slew is complete. Tracking..."); 164 343 } … … 166 345 { 167 346 TrackState = SCOPE_PARKED; 347 EqNV->s = IPS_IDLE; 168 348 IDMessage(deviceName(), "Telescope parked successfully."); 169 349 } 170 350 } 171 //else172 // IDSetNumber(&eqNP, NULL);173 351 174 352 break; … … 176 354 case SCOPE_TRACKING: 177 355 /* 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 180 467 break; 181 468 … … 200 487 Parked=false; 201 488 TrackState = SCOPE_SLEWING; 489 490 EqReqNV->s = IPS_BUSY; 491 EqNV->s = IPS_BUSY; 492 202 493 IDMessage(deviceName(), "Slewing to RA: %s - DEC: %s", RAStr, DecStr); 203 494 return true; … … 214 505 } 215 506 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 507 bool 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 561 bool 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 632 bool 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 664 bool 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 15 15 16 16 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 17 38 public: 18 39 ScopeSim(); … … 24 45 virtual bool Disconnect(); 25 46 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); 26 55 27 56 bool Goto(double,double); -
BAORadio/libindi/libindi/drivers/telescope/temmadriver.c
r490 r642 803 803 804 804 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){ 806 806 local_buffer[7]=0; 807 807 if (strstr(local_buffer,"on")){ /* stanby on */ -
BAORadio/libindi/libindi/drivers/video/v4ldriver.cpp
r490 r642 565 565 int status=0; 566 566 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 569 577 fits_write_date(fptr, &status); 570 578 } -
BAORadio/libindi/libindi/eventloop.c
r490 r642 422 422 if (ns < 0) { 423 423 perror ("select"); 424 exit(1);424 return; 425 425 } 426 426 … … 480 480 if (read (fd, &c, 1) != 1) { 481 481 perror ("read"); 482 exit(1);482 return; 483 483 } 484 484 -
BAORadio/libindi/libindi/examples/tutorial_dome.c
r490 r642 45 45 #define SNOOP_GROUP "Snooped" 46 46 47 void closeDome(); 48 47 49 /* Connect/Disconnect */ 48 50 static ISwitch PowerS[] = {{"CONNECT" , "Connect" , ISS_OFF, 0, 0},{"DISCONNECT", "Disconnect", ISS_ON, 0, 0}}; -
BAORadio/libindi/libindi/examples/tutorial_four.cpp
r504 r642 199 199 { 200 200 // Ignore if not ours 201 if (strcmp (dev, device ID))201 if (strcmp (dev, deviceName())) 202 202 return false; 203 203 … … 212 212 213 213 // Ignore if not ours 214 if (strcmp (dev, device ID))214 if (strcmp (dev, deviceName())) 215 215 return false; 216 216 … … 239 239 { 240 240 // ignore if not ours // 241 if (strcmp (dev, device ID))241 if (strcmp (dev, deviceName())) 242 242 return false; 243 243 … … 258 258 }*/ 259 259 260 return DefaultDriver::ISNewSwitch(dev, name, states, names, n); 261 260 262 261 263 } -
BAORadio/libindi/libindi/indiapi.h
r504 r642 46 46 <ul> 47 47 <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> 48 50 <li><a href="indicom_8h.html">INDI Common Routine Library</a></li> 49 51 <li><a href="lilxml_8h.html">INDI LilXML Library</a></li> 50 52 <li><a href="group__configFunctions.html">Configuration</a></li> 51 <li><a href="classINDI_1_1BaseClient.html">Client API</a></li>52 53 </ul> 53 54 … … 75 76 76 77 /* INDI Library version */ 77 #define INDI_LIBV 0. 878 #define INDI_LIBV 0.9 78 79 79 80 /******************************************************************************* -
BAORadio/libindi/libindi/indidriver.c
r504 r642 236 236 { 237 237 np = IUFindNumber(nvp, names[i]); 238 np->value = values[i]; 238 np->value = values[i]; 239 239 } 240 240 -
BAORadio/libindi/libindi/indiserver.c
r504 r642 752 752 while ( fgets (line, MAXRBUF, fifo.fs) != NULL) 753 753 { 754 fprintf(stderr, "FIFO: %s\n", line); 754 if (verbose) 755 fprintf(stderr, "FIFO: %s\n", line); 755 756 756 757 tDev[0] = '\0', tDriver[0] = '\0', tConfig[0] = '\0', envDev[0] = '\0', envConfig[0] = '\0'; … … 789 790 else if (strstr(token, "\"") || strstr(token, "'")) 790 791 { 791 strncat(tDev, ++token, MAXRBUF);792 strncat(tDev, ++token, sizeof(tDev)-strlen(tDev)-1); 792 793 while (token = strsep(&cp, delm) ) 793 794 { 794 795 strcat(tDev, " "); 795 strncat(tDev, token, MAXRBUF);796 strncat(tDev, token, sizeof(tDev)-strlen(tDev)-1); 796 797 if ( (tp=strchr(tDev, '\"')) || (tp=strchr(tDev, '\''))) 797 798 { … … 816 817 if (strstr(token, "\"") || strstr(token, "'")) 817 818 { 818 strncat(tConfig, ++token, MAXRBUF);819 strncat(tConfig, ++token, sizeof(tConfig)-strlen(tDev)-1); 819 820 while (token = strsep(&cp, delm) ) 820 821 { 821 822 strcat(tConfig, " "); 822 strncat(tConfig, token, MAXRBUF);823 strncat(tConfig, token, sizeof(tConfig)-strlen(tDev)-1); 823 824 824 825 if ( (tp=strchr(tConfig, '\"')) || (tp=strchr(tConfig, '\''))) … … 876 877 for (dp = dvrinfo; dp < &dvrinfo[ndvrinfo]; dp++) 877 878 { 878 if (!strcmp(dp->name, tDriver) )879 if (!strcmp(dp->name, tDriver) && dp->active==1) 879 880 { 880 881 /* If device name is given, check against it before shutting down */ -
BAORadio/libindi/libindi/libindi.pc.cmake
r501 r642 6 6 Name: libindi 7 7 Description: Instrument Neutral Distributed Interface 8 URL =http://www.indilib.org/8 URL: http://www.indilib.org/ 9 9 Version: @CMAKE_INDI_VERSION_STRING@ 10 Libs: -L @LIB_DESTINATION@-lindi11 Cflags: -I @INCLUDE_INSTALL_DIR@ -@INCLUDE_INSTALL_DIR@/libindi10 Libs: -L${libdir} -lindi 11 Cflags: -I${includedir} -I${includedir}/libindi 12 12 -
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 1 19 #include <stdlib.h> 2 20 #include <string.h> … … 159 177 INDI::BaseDriver * INDI::BaseClient::getDriver(const char * deviceName) 160 178 { 161 vector< devicePtr>::const_iterator devi;179 vector<INDI::BaseDriver *>::const_iterator devi; 162 180 for ( devi = cDevices.begin(); devi != cDevices.end(); devi++) 163 181 if (!strcmp(deviceName, (*devi)->deviceName())) 164 return (*devi) .get();182 return (*devi); 165 183 166 184 return NULL; … … 170 188 { 171 189 (static_cast<INDI::BaseClient *> (context))->listenINDI(); 190 return NULL; 172 191 } 173 192 … … 291 310 int INDI::BaseClient::removeDevice( const char * devName, char * errmsg ) 292 311 { 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();) 296 315 { 297 316 if (strcmp(devName, (*devicei)->deviceName())) 298 317 { 299 cDevices.erase(devicei);300 //delete (*devicei);318 delete *devicei; 319 devicei = cDevices.erase(devicei); 301 320 return 0; 302 321 } 303 304 devicei++;322 else 323 ++devicei; 305 324 } 306 325 … … 312 331 { 313 332 314 std::vector< devicePtr>::const_iterator devicei;333 std::vector<INDI::BaseDriver *>::const_iterator devicei; 315 334 316 335 for (devicei = cDevices.begin(); devicei != cDevices.end(); devicei++) 317 336 { 318 337 if (!strcmp(devName, (*devicei)->deviceName())) 319 return (*devicei) .get();338 return (*devicei); 320 339 321 340 } … … 328 347 INDI::BaseDriver * INDI::BaseClient::addDevice (XMLEle *dep, char * errmsg) 329 348 { 330 devicePtr dp(new INDI::BaseDriver()); 349 //devicePtr dp(new INDI::BaseDriver()); 350 INDI::BaseDriver *dp = new INDI::BaseDriver(); 331 351 XMLAtt *ap; 332 352 char * device_name; … … 350 370 351 371 /* ok */ 352 return dp .get();372 return dp; 353 373 } 354 374 -
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 1 19 #ifndef INDIBASECLIENT_H 2 20 #define INDIBASECLIENT_H … … 4 22 #include <vector> 5 23 #include <map> 6 #include <boost/shared_ptr.hpp>7 24 #include <string> 8 25 … … 26 43 \attention All notifications functions defined in INDI::BaseMediator must be implemented in the client class even if 27 44 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. 28 47 \author Jasem Mutlaq 29 48 … … 33 52 public: 34 53 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; 36 55 37 56 BaseClient(); … … 82 101 /** \returns Returns a vector of all devices created in the client. 83 102 */ 84 const vector< devicePtr> & getDrivers() const { return cDevices; }103 const vector<INDI::BaseDriver *> & getDrivers() const { return cDevices; } 85 104 86 105 /** \brief Set Binary Large Object policy mode … … 152 171 pthread_t listen_thread; 153 172 154 vector< devicePtr> cDevices;173 vector<INDI::BaseDriver *> cDevices; 155 174 vector<string> cDeviceNames; 156 175 -
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 1 19 #include <stdlib.h> 2 20 #include <string.h> … … 9 27 #include "base64.h" 10 28 29 PropertyContainer::PropertyContainer() 30 { 31 pPtr = NULL; 32 pRegistered = false; 33 pDynamic = false; 34 pType = INDI_UNKNOWN; 35 } 36 37 PropertyContainer::~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 69 void PropertyContainer::setProperty(void *p) 70 { 71 pRegistered = true; 72 pPtr = p; 73 74 } 75 76 void PropertyContainer::setType(INDI_TYPE t) 77 { 78 pType = t; 79 } 80 81 void PropertyContainer::setRegistered(bool r) 82 { 83 pRegistered = r; 84 } 85 86 void PropertyContainer::setDynamic(bool d) 87 { 88 pDynamic = d; 89 } 90 11 91 INDI::BaseDriver::BaseDriver() 12 92 { 13 93 mediator = NULL; 14 94 lp = newLilXML(); 95 char indidev[MAXINDIDEVICE]; 96 strncpy(indidev, "INDIDEV=", MAXINDIDEVICE); 15 97 16 98 if (getenv("INDIDEV") != NULL) 17 99 { 18 strncpy(deviceID, getenv("INDIDEV"), MAXINDI NAME);19 putenv( "INDIDEV=");100 strncpy(deviceID, getenv("INDIDEV"), MAXINDIDEVICE); 101 putenv(indidev); 20 102 } 21 103 } … … 25 107 { 26 108 delLilXML (lp); 109 while(!pAll.empty()) 110 { 111 delete pAll.back(); 112 pAll.pop_back(); 113 } 27 114 } 28 115 … … 31 118 INumberVectorProperty * nvp = NULL; 32 119 33 nvp = static_cast<INumberVectorProperty *> (getProperty(name, INDI_NUMBER));120 nvp = static_cast<INumberVectorProperty *> (getProperty(name, PropertyContainer::INDI_NUMBER)); 34 121 35 122 return nvp; … … 40 127 ITextVectorProperty * tvp = NULL; 41 128 42 tvp = static_cast<ITextVectorProperty *> (getProperty(name, INDI_TEXT));129 tvp = static_cast<ITextVectorProperty *> (getProperty(name, PropertyContainer::INDI_TEXT)); 43 130 44 131 return tvp; … … 49 136 ISwitchVectorProperty * svp = NULL; 50 137 51 svp = static_cast<ISwitchVectorProperty *> (getProperty(name, INDI_SWITCH));138 svp = static_cast<ISwitchVectorProperty *> (getProperty(name, PropertyContainer::INDI_SWITCH)); 52 139 53 140 return svp; … … 58 145 ILightVectorProperty * lvp = NULL; 59 146 60 lvp = static_cast<ILightVectorProperty *> (getProperty(name, INDI_LIGHT));147 lvp = static_cast<ILightVectorProperty *> (getProperty(name, PropertyContainer::INDI_LIGHT)); 61 148 62 149 return lvp; … … 67 154 IBLOBVectorProperty * bvp = NULL; 68 155 69 bvp = static_cast<IBLOBVectorProperty *> (getProperty(name, INDI_BLOB));156 bvp = static_cast<IBLOBVectorProperty *> (getProperty(name, PropertyContainer::INDI_BLOB)); 70 157 71 158 return bvp; 72 159 } 73 160 74 void * INDI::BaseDriver::getProperty(const char *name, INDI_TYPE type) 75 { 76 std::map< boost::shared_ptr<void>, INDI_TYPE>::iterator orderi; 161 void * 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; 77 168 78 169 INumberVectorProperty *nvp; … … 84 175 for (orderi = pAll.begin(); orderi != pAll.end(); orderi++) 85 176 { 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) 87 182 continue; 88 183 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; 115 226 break; 116 227 } … … 121 232 } 122 233 123 int INDI::BaseDriver::removeProperty(const char *name) 124 { 125 std::map< boost::shared_ptr<void>, INDI_TYPE>::iterator orderi; 234 PropertyContainer * 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; 126 241 127 242 INumberVectorProperty *nvp; … … 133 248 for (orderi = pAll.begin(); orderi != pAll.end(); orderi++) 134 249 { 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 307 int 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); 139 329 if (!strcmp(name, nvp->name)) 140 330 { 141 pAll.erase(orderi);331 (*orderi)->setRegistered(false); 142 332 return 0; 143 333 } 144 334 break; 145 case INDI_TEXT:146 tvp = static_cast<ITextVectorProperty *>( (orderi->first).get());335 case PropertyContainer::INDI_TEXT: 336 tvp = static_cast<ITextVectorProperty *>(pPtr); 147 337 if (!strcmp(name, tvp->name)) 148 338 { 149 pAll.erase(orderi);339 (*orderi)->setRegistered(false); 150 340 return 0; 151 341 } 152 342 break; 153 case INDI_SWITCH:154 svp = static_cast<ISwitchVectorProperty *>( (orderi->first).get());343 case PropertyContainer::INDI_SWITCH: 344 svp = static_cast<ISwitchVectorProperty *>(pPtr); 155 345 if (!strcmp(name, svp->name)) 156 346 { 157 pAll.erase(orderi);347 (*orderi)->setRegistered(false); 158 348 return 0; 159 349 } 160 350 break; 161 case INDI_LIGHT:162 lvp = static_cast<ILightVectorProperty *>( (orderi->first).get());351 case PropertyContainer::INDI_LIGHT: 352 lvp = static_cast<ILightVectorProperty *>(pPtr); 163 353 if (!strcmp(name, lvp->name)) 164 354 { 165 pAll.erase(orderi);355 (*orderi)->setRegistered(false); 166 356 return 0; 167 357 } 168 358 break; 169 case INDI_BLOB:170 bvp = static_cast<IBLOBVectorProperty *>( (orderi->first).get());359 case PropertyContainer::INDI_BLOB: 360 bvp = static_cast<IBLOBVectorProperty *>(pPtr); 171 361 if (!strcmp(name, bvp->name)) 172 362 { 173 pAll.erase(orderi);363 (*orderi)->setRegistered(false); 174 364 return 0; 175 365 } … … 215 405 IPerm perm; 216 406 IPState state; 217 ISRule rule;218 407 XMLEle *ep = NULL; 219 408 char *rtag, *rname, *rdev; 220 //INDI_TYPE type;221 409 double timeout=0; 222 410 … … 258 446 if (!strcmp (rtag, "defNumberVector")) 259 447 { 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 264 451 INumber *np = NULL; 265 452 int n=0; … … 281 468 np = (INumber *) realloc(np, (n+1) * sizeof(INumber)); 282 469 283 np[n].nvp = nvp .get();470 np[n].nvp = nvp; 284 471 285 472 XMLAtt *na = findXMLAtt (ep, "name"); … … 320 507 nvp->nnp = n; 321 508 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 327 516 //IDLog("Adding number property %s to list.\n", nvp->name); 328 517 if (mediator) … … 334 523 else if (!strcmp (rtag, "defSwitchVector")) 335 524 { 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 339 528 ISwitch *sp = NULL; 340 529 int n=0; … … 360 549 sp = (ISwitch *) realloc(sp, (n+1) * sizeof(ISwitch)); 361 550 362 sp[n].svp = svp .get();551 sp[n].svp = svp; 363 552 364 553 XMLAtt *na = findXMLAtt (ep, "name"); … … 380 569 svp->nsp = n; 381 570 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); 387 577 //IDLog("Adding Switch property %s to list.\n", svp->name); 388 578 if (mediator) … … 396 586 { 397 587 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; 401 590 IText *tp = NULL; 402 591 int n=0; … … 418 607 tp = (IText *) realloc(tp, (n+1) * sizeof(IText)); 419 608 420 tp[n].tvp = tvp .get();609 tp[n].tvp = tvp; 421 610 422 611 XMLAtt *na = findXMLAtt (ep, "name"); … … 439 628 tvp->ntp = n; 440 629 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); 446 636 //IDLog("Adding Text property %s to list.\n", tvp->name); 447 637 if (mediator) … … 454 644 { 455 645 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; 459 648 ILight *lp = NULL; 460 649 int n=0; … … 474 663 lp = (ILight *) realloc(lp, (n+1) * sizeof(ILight)); 475 664 476 lp[n].lvp = lvp .get();665 lp[n].lvp = lvp; 477 666 478 667 XMLAtt *na = findXMLAtt (ep, "name"); … … 495 684 lvp->nlp = n; 496 685 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 502 693 //IDLog("Adding Light property %s to list.\n", lvp->name); 503 694 if (mediator) … … 509 700 else if (!strcmp (rtag, "defBLOBVector")) 510 701 { 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; 515 704 IBLOB *bp = NULL; 516 705 int n=0; … … 530 719 bp = (IBLOB *) realloc(bp, (n+1) * sizeof(IBLOB)); 531 720 532 bp[n].bvp = bvp .get();721 bp[n].bvp = bvp; 533 722 534 723 XMLAtt *na = findXMLAtt (ep, "name"); … … 560 749 bvp->nbp = n; 561 750 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); 567 757 //IDLog("Adding BLOB property %s to list.\n", bvp->name); 568 758 if (mediator) … … 913 1103 } 914 1104 915 void INDI::BaseDriver::registerProperty(void *p, INDI_TYPE type)916 { 917 918 919 if (type == INDI_NUMBER)1105 void INDI::BaseDriver::registerProperty(void *p, PropertyContainer::INDI_TYPE type) 1106 { 1107 PropertyContainer *pContainer; 1108 1109 if (type == PropertyContainer::INDI_NUMBER) 920 1110 { 921 1111 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); 923 1115 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) 930 1126 { 931 1127 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); 933 1132 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 939 1142 } 940 else if (type == INDI_SWITCH)1143 else if (type == PropertyContainer::INDI_SWITCH) 941 1144 { 942 1145 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); 944 1150 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) 954 1161 { 955 1162 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); 957 1167 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); 962 1175 } 963 else if (type == INDI_BLOB)1176 else if (type == PropertyContainer::INDI_BLOB) 964 1177 { 965 1178 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); 967 1183 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 1 19 #ifndef INDIBASEDRIVER_H 2 20 #define INDIBASEDRIVER_H 3 21 4 #include <boost/shared_ptr.hpp> 5 #include <map> 22 #include <vector> 6 23 #include <string> 7 24 … … 11 28 12 29 #define MAXRBUF 2048 30 31 class PropertyContainer 32 { 33 public: 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 58 private: 59 void *pPtr; 60 INDI_TYPE pType; 61 bool pRegistered; 62 bool pDynamic; 63 }; 13 64 14 65 /** … … 37 88 }; 38 89 39 /*! INDI property type */40 typedef enum41 {42 INDI_NUMBER, /*!< INumberVectorProperty. */43 INDI_SWITCH, /*!< ISwitchVectorProperty. */44 INDI_TEXT, /*!< ITextVectorProperty. */45 INDI_LIGHT, /*!< ILightVectorProperty. */46 INDI_BLOB, /*!< IBLOBVectorProperty. */47 INDI_UNKNOWN48 } INDI_TYPE;49 50 90 /** \return Return vector number property given its name */ 51 91 INumberVectorProperty * getNumber(const char *name); … … 59 99 IBLOBVectorProperty * getBLOB(const char *name); 60 100 61 void registerProperty(void *p, INDI_TYPE type);101 void registerProperty(void *p, PropertyContainer::INDI_TYPE type); 62 102 63 103 /** \brief Remove a property … … 77 117 78 118 */ 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); 80 122 81 123 /** \brief Build driver properties from a skeleton file. … … 133 175 int setBLOB(IBLOBVectorProperty *pp, XMLEle * root, char * errmsg); 134 176 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;142 177 143 178 private: 144 179 145 std::map< boost::shared_ptr<void>, INDI_TYPE> pAll; 180 char deviceID[MAXINDINAME]; 181 182 std::vector<PropertyContainer *> pAll; 146 183 147 184 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 1 19 #include <stdlib.h> 2 20 #include <string.h> … … 8 26 #include "base64.h" 9 27 28 const char *COMMUNICATION_TAB = "Communication"; 29 const char *MAIN_CONTROL_TAB = "Main Control"; 30 const char *MOTION_TAB = "Motion Control"; 31 const char *DATETIME_TAB = "Date/Time"; 32 const char *SITE_TAB = "Site Management"; 33 const char *OPTIONS_TAB = "Options"; 34 const char *FILTER_TAB = "Filter Wheel"; 35 const char *GUIDER_TAB = "Guide Wheel"; 36 10 37 void timerfunc(void *t) 11 38 { … … 30 57 //switchPtr conSw(new ISwitchVectorProperty); 31 58 ConnectionSP = new ISwitchVectorProperty; 59 DebugSP = NULL; 60 SimulationSP = NULL; 61 ConfigProcessSP = NULL; 32 62 33 63 IUFillSwitch(&ConnectionS[0],"CONNECT","Connect",ISS_OFF); … … 35 65 IUFillSwitchVector(ConnectionSP,ConnectionS,2,deviceName(),"CONNECTION","Connection","Main Control",IP_RW,ISR_1OFMANY,60,IPS_IDLE); 36 66 37 registerProperty(ConnectionSP, INDI_SWITCH); 38 67 registerProperty(ConnectionSP, PropertyContainer::INDI_SWITCH); 68 69 } 70 71 INDI::DefaultDriver::~DefaultDriver() 72 { 73 delete ConnectionSP; 74 delete DebugSP; 75 delete SimulationSP; 76 delete ConfigProcessSP; 39 77 } 40 78 … … 47 85 48 86 if (pResult) 49 IDMessage(deviceID, "Configuration successfully loaded."); 87 IDMessage(deviceID, "Configuration successfully loaded.\n"); 88 else 89 IDMessage(deviceID,"Error loading configuration\n"); 50 90 51 91 IUSaveDefaultConfig(NULL, NULL, deviceID); … … 54 94 } 55 95 56 bool INDI::DefaultDriver::saveConfig() 57 { 58 //std::vector<orderPtr>::iterator orderi; 59 60 std::map< boost::shared_ptr<void>, INDI_TYPE>::iterator orderi; 96 bool INDI::DefaultDriver::saveConfigItems(FILE *fp) 97 { 98 std::vector<PropertyContainer *>::iterator orderi; 99 100 PropertyContainer::INDI_TYPE pType; 101 void *pPtr; 61 102 62 103 ISwitchVectorProperty *svp=NULL; … … 64 105 ITextVectorProperty *tvp=NULL; 65 106 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);78 107 79 108 for (orderi = pAll.begin(); orderi != pAll.end(); orderi++) 80 109 { 81 110 82 switch (orderi->second) 111 pType = (*orderi)->getType(); 112 pPtr = (*orderi)->getProperty(); 113 114 switch (pType) 83 115 { 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); 87 119 IUSaveConfigNumber(fp, nvp); 88 120 break; 89 case INDI_TEXT:90 tvp = static_cast<ITextVectorProperty *>( (orderi->first).get());121 case PropertyContainer::INDI_TEXT: 122 tvp = static_cast<ITextVectorProperty *>(pPtr); 91 123 IUSaveConfigText(fp, tvp); 92 124 break; 93 case INDI_SWITCH:94 svp = static_cast<ISwitchVectorProperty *>( (orderi->first).get());125 case PropertyContainer::INDI_SWITCH: 126 svp = static_cast<ISwitchVectorProperty *>(pPtr); 95 127 /* Never save CONNECTION property. Don't save switches with no switches on if the rule is one of many */ 96 128 if (!strcmp(svp->name, "CONNECTION") || (svp->r == ISR_1OFMANY && !IUFindOnSwitch(svp))) … … 98 130 IUSaveConfigSwitch(fp, svp); 99 131 break; 100 case INDI_BLOB:101 bvp = static_cast<IBLOBVectorProperty *>( (orderi->first).get());132 case PropertyContainer::INDI_BLOB: 133 bvp = static_cast<IBLOBVectorProperty *>(pPtr); 102 134 IUSaveConfigBLOB(fp, bvp); 103 135 break; 104 136 } 105 137 } 138 return true; 139 } 140 141 bool 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); 106 159 107 160 IUSaveConfigTag(fp, 1); … … 142 195 bool INDI::DefaultDriver::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) 143 196 { 144 145 197 // ignore if not ours // 146 198 if (strcmp (dev, deviceID)) … … 160 212 if ( !strcmp(names[i], "CONNECT") && (states[i] == ISS_ON)) 161 213 { 214 162 215 // If not connected, attempt to connect 163 216 if (isConnected() == false) … … 167 220 // If connection is successful, set it thus 168 221 if (rc) 169 setConnected(true);222 setConnected(true, IPS_OK); 170 223 else 171 setConnected(false, IPS_ALERT); 224 setConnected(false, IPS_ALERT); 225 172 226 173 227 updateProperties(); … … 261 315 if (!DebugSP) 262 316 { 263 switchPtr debSw(new ISwitchVectorProperty); 264 DebugSP = debSw.get(); 317 DebugSP = new ISwitchVectorProperty; 265 318 IUFillSwitch(&DebugS[0], "ENABLE", "Enable", ISS_OFF); 266 319 IUFillSwitch(&DebugS[1], "DISABLE", "Disable", ISS_ON); 267 IUFillSwitchVector(DebugSP, DebugS, NARRAY(DebugS), device ID, "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); 269 322 } 270 323 else … … 285 338 if (!SimulationSP) 286 339 { 287 switchPtr simSw(new ISwitchVectorProperty); 288 SimulationSP = simSw.get(); 340 SimulationSP = new ISwitchVectorProperty; 289 341 IUFillSwitch(&SimulationS[0], "ENABLE", "Enable", ISS_OFF); 290 342 IUFillSwitch(&SimulationS[1], "DISABLE", "Disable", ISS_ON); 291 IUFillSwitchVector(SimulationSP, SimulationS, NARRAY(SimulationS), device ID, "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); 293 345 } 294 346 else … … 307 359 if (!ConfigProcessSP) 308 360 { 309 switchPtr configSw(new ISwitchVectorProperty); 310 ConfigProcessSP = configSw.get(); 361 ConfigProcessSP = new ISwitchVectorProperty; 311 362 IUFillSwitch(&ConfigProcessS[0], "CONFIG_LOAD", "Load", ISS_OFF); 312 363 IUFillSwitch(&ConfigProcessS[1], "CONFIG_SAVE", "Save", ISS_OFF); 313 364 IUFillSwitch(&ConfigProcessS[2], "CONFIG_DEFAULT", "Default", ISS_OFF); 314 IUFillSwitchVector(ConfigProcessSP, ConfigProcessS, NARRAY(ConfigProcessS), device ID, "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); 316 367 } 317 368 /**************************************************************************/ … … 416 467 void INDI::DefaultDriver::ISGetProperties (const char *dev) 417 468 { 418 std:: map< boost::shared_ptr<void>, INDI_TYPE>::iterator orderi;469 std::vector<PropertyContainer *>::iterator orderi; 419 470 static int isInit = 0; 420 421 //fprintf(stderr,"Enter ISGetProperties '%s'\n",dev); 471 PropertyContainer::INDI_TYPE pType; 472 void *pPtr; 473 422 474 if(isInit == 0) 423 475 { … … 442 494 for (orderi = pAll.begin(); orderi != pAll.end(); orderi++) 443 495 { 444 switch (orderi->second) 496 pType = (*orderi)->getType(); 497 pPtr = (*orderi)->getProperty(); 498 499 switch (pType) 445 500 { 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); 460 515 break; 461 516 } … … 535 590 // This is a helper function 536 591 // 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);592 int INDI::DefaultDriver::SetTimer(int ms) 593 { 594 return IEAddTimer(ms,timerfunc,this); 540 595 } 541 596 542 597 // Just another helper to help encapsulate indi into a clean class 543 void INDI::DefaultDriver::RemoveTimer(int t)544 { 545 IERmTimer( t);598 void INDI::DefaultDriver::RemoveTimer(int id) 599 { 600 IERmTimer(id); 546 601 return; 547 602 } … … 577 632 void INDI::DefaultDriver::defineNumber(INumberVectorProperty *nvp) 578 633 { 579 registerProperty(nvp, INDI_NUMBER);634 registerProperty(nvp, PropertyContainer::INDI_NUMBER); 580 635 IDDefNumber(nvp, NULL); 581 636 } … … 583 638 void INDI::DefaultDriver::defineText(ITextVectorProperty *tvp) 584 639 { 585 registerProperty(tvp, INDI_TEXT);640 registerProperty(tvp, PropertyContainer::INDI_TEXT); 586 641 IDDefText(tvp, NULL); 587 642 } … … 589 644 void INDI::DefaultDriver::defineSwitch(ISwitchVectorProperty *svp) 590 645 { 591 registerProperty(svp, INDI_SWITCH);646 registerProperty(svp, PropertyContainer::INDI_SWITCH); 592 647 IDDefSwitch(svp, NULL); 593 648 } … … 595 650 void INDI::DefaultDriver::defineLight(ILightVectorProperty *lvp) 596 651 { 597 registerProperty(lvp, INDI_LIGHT);652 registerProperty(lvp, PropertyContainer::INDI_LIGHT); 598 653 IDDefLight(lvp, NULL); 599 654 } … … 601 656 void INDI::DefaultDriver::defineBLOB(IBLOBVectorProperty *bvp) 602 657 { 603 registerProperty(bvp, INDI_BLOB);658 registerProperty(bvp, PropertyContainer::INDI_BLOB); 604 659 IDDefBLOB(bvp, NULL); 605 660 } -
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 1 19 #ifndef INDIDEFAULTDRIVER_H 2 20 #define INDIDEFAULTDRIVER_H … … 5 23 #include "indidriver.h" 6 24 25 #include <auto_ptr.h> 26 27 extern const char *COMMUNICATION_TAB; 28 extern const char *MAIN_CONTROL_TAB; 29 extern const char *MOTION_TAB; 30 extern const char *DATETIME_TAB; 31 extern const char *SITE_TAB; 32 extern const char *OPTIONS_TAB; 33 extern const char *FILTER_TAB; 34 extern const char *GUIDER_TAB; 35 7 36 /** 8 37 * \class INDI::DefaultDriver 9 \brief Class to provide extended functiona ry for drivers in addition38 \brief Class to provide extended functionality for drivers in addition 10 39 to the functionality provided by INDI::BaseDriver. This class should \e only be subclassed by 11 40 drivers directly as it is linked with main(). Virtual drivers cannot employ INDI::DefaultDriver. … … 21 50 public: 22 51 DefaultDriver(); 23 virtual ~DefaultDriver() {}52 virtual ~DefaultDriver(); 24 53 25 54 /** \brief Add Debug, Simulation, and Configuration options to the driver */ … … 74 103 virtual bool deleteProperty(const char *propertyName); 75 104 76 /** \brief Connect or Disconnect a device. 105 106 /** \brief Set connection switch status in the client. 77 107 \param status If true, the driver will attempt to connect to the device (CONNECT=ON). If false, it will attempt 78 108 to 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. 80 112 */ 81 113 virtual void setConnected(bool status, IPState state=IPS_OK, const char *msg = NULL); 82 114 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. */ 85 127 virtual void TimerHit(); 86 128 … … 116 158 \return True if successful, false otherwise. 117 159 */ 118 bool loadConfig();160 virtual bool loadConfig(); 119 161 120 162 /** \brief Save the current properties in a configuration file 121 163 \return True if successful, false otherwise. 122 164 */ 123 bool saveConfig(); 165 virtual bool saveConfig(); 166 virtual bool saveConfigItems(FILE *fp); 124 167 125 168 /** \brief Load the default configuration file 126 169 \return True if successful, false otherwise. 127 170 */ 128 bool loadDefaultConfig(); 171 virtual bool loadDefaultConfig(); 172 129 173 130 174 // Simulatin & Debug -
BAORadio/libindi/libindi/libs/indibase/indibase.h
r504 r642 9 9 /** 10 10 * \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. 12 14 13 15 <ul> … … 18 20 <li>DefaultDriver: INDI::BaseDriver with extended functionality such as debug, simulation, and configuration support. 19 21 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> 20 29 </ul> 21 30 */ … … 26 35 class BaseDriver; 27 36 class DefaultDriver; 37 class FilterInterface; 38 class GuiderInterface; 28 39 class CCD; 29 40 class Telescope; 30 41 class FilterWheel; 31 42 class Focuser; 32 class USBDevice; 43 class USBDevice; 33 44 } 34 45 -
BAORadio/libindi/libindi/libs/indibase/indiccd.cpp
r504 r642 1 1 /******************************************************************************* 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. 20 17 *******************************************************************************/ 21 18 … … 24 21 #include <string.h> 25 22 26 #include <fitsio.h>27 23 #include <zlib.h> 28 24 25 const char *IMAGE_SETTINGS_TAB = "Image Settings"; 26 const char *IMAGE_INFO_TAB = "Image Info"; 27 const char *GUIDE_HEAD_TAB = "Guide Head"; 28 const char *GUIDE_CONTROL_TAB = "Guider Control"; 29 30 CCDChip::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 50 CCDChip::~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 65 int CCDChip::setFrameType(CCD_FRAME t) 66 { 67 //fprintf(stderr,"Set frame type to %d\n",t); 68 FrameType=t; 69 return 0; 70 } 71 72 void 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 83 void 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 98 void 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 109 void 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 122 void CCDChip::setBPP(int bbp) 123 { 124 BPP = bbp; 125 126 ImagePixelSizeN[5].value = BPP; 127 128 IDSetNumber(ImagePixelSizeNP, NULL); 129 } 130 131 void CCDChip::setFrameBufferSize(int nbuf) 132 { 133 if (RawFrame != NULL) 134 delete RawFrame; 135 136 RawFrameSize = nbuf; 137 138 RawFrame = new char[nbuf]; 139 } 140 141 void CCDChip::setExposure(double duration) 142 { 143 ImageExposureN[0].value = duration; 144 IDSetNumber(ImageExposureNP, NULL); 145 } 146 147 void CCDChip::setInterlaced(bool intr) 148 { 149 Interlaced = intr; 150 } 151 152 void CCDChip::setExposureFailed() 153 { 154 ImageExposureNP->s = IPS_ALERT; 155 IDSetNumber(ImageExposureNP, NULL); 156 } 157 29 158 INDI::CCD::CCD() 30 159 { 31 160 //ctor 32 SendCompressed=false;33 GuiderCompressed=false;34 161 HasGuideHead=false; 35 162 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; 45 165 } 46 166 47 167 INDI::CCD::~CCD() 48 168 { 49 //dtor169 delete TelescopeTP; 50 170 } 51 171 52 172 bool INDI::CCD::initProperties() 53 173 { 54 //IDLog("INDI::CCD initProperties '%s'\n",deviceName());55 56 174 DefaultDriver::initProperties(); // let the base class flesh in what it wants 57 175 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; 148 251 } 149 252 … … 162 265 { 163 266 //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 { 171 275 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); 183 281 if(HasGuideHead) 184 282 { 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); 187 291 } 188 292 if(HasSt4Port) 189 293 { 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); 215 324 } 216 325 return true; 217 326 } 218 327 328 void 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 350 bool 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 219 380 bool INDI::CCD::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) 220 381 { 221 382 // first check if it's for our device 222 383 //IDLog("INDI::CCD::ISNewNumber %s\n",name); 223 if(strcmp(dev,deviceName())==0) { 384 if(strcmp(dev,deviceName())==0) 385 { 224 386 // This is for our device 225 387 // 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 { 227 390 float n; 228 391 int rc; … … 230 393 n=values[0]; 231 394 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; 234 401 // now we have a new number, this is our requested exposure time 235 402 // Tell the clients we are busy with this exposure … … 237 404 // And now call the physical hardware layer to start the exposure 238 405 rc=StartExposure(n); 239 switch(rc) { 406 switch(rc) 407 { 240 408 case 0: // normal case, exposure running on timers, callbacks when it's finished 241 ImageExposureNV.s=IPS_BUSY;409 PrimaryCCD.ImageExposureNP->s=IPS_BUSY; 242 410 break; 243 411 case 1: // Short exposure, it's already done 244 ImageExposureNV.s=IPS_OK;412 PrimaryCCD.ImageExposureNP->s=IPS_OK; 245 413 break; 246 414 case -1: // error condition 247 ImageExposureNV.s=IPS_ALERT;415 PrimaryCCD.ImageExposureNP->s=IPS_ALERT; 248 416 break; 249 417 } 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 { 255 424 float n; 256 425 int rc; … … 258 427 n=values[0]; 259 428 260 Guide rExposureN[0].value=n;261 Guide rExposureNV.s=IPS_BUSY;429 GuideCCD.ImageExposureN[0].value=n; 430 GuideCCD.ImageExposureNP->s=IPS_BUSY; 262 431 // now we have a new number, this is our requested exposure time 263 432 // Tell the clients we are busy with this exposure … … 270 439 switch(rc) { 271 440 case 0: // normal case, exposure running on timers, callbacks when it's finished 272 Guide rExposureNV.s=IPS_BUSY;441 GuideCCD.ImageExposureNP->s=IPS_BUSY; 273 442 break; 274 443 case 1: // Short exposure, it's already done 275 Guide rExposureNV.s=IPS_OK;444 GuideCCD.ImageExposureNP->s=IPS_OK; 276 445 break; 277 446 case -1: // error condition 278 Guide rExposureNV.s=IPS_ALERT;447 GuideCCD.ImageExposureNP->s=IPS_ALERT; 279 448 break; 280 449 } 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 { 285 456 // 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); 288 475 // 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 { 296 493 // 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); 299 496 // 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); 314 516 // 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 { 337 523 GuideNorth(GuideNS[0].value); 338 524 } … … 342 528 GuideNS[0].value=0; 343 529 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 { 350 538 // We are being asked to send a guide pulse north/south on the st4 port 351 GuideEW V.s=IPS_BUSY;352 IUUpdateNumber( &GuideEWV,values,names,n);539 GuideEWP->s=IPS_BUSY; 540 IUUpdateNumber(GuideEWP,values,names,n); 353 541 // Update client display 354 IDSetNumber( &GuideEWV,NULL);542 IDSetNumber(GuideEWP,NULL); 355 543 356 544 fprintf(stderr,"GuiderEastWest set to %6.3f,%6.3f\n", 357 545 GuideEW[0].value,GuideEW[1].value); 358 546 359 if(GuideEW[0].value != 0) { 547 if(GuideEW[0].value != 0) 548 { 360 549 GuideEast(GuideEW[0].value); 361 } else { 550 } else 551 { 362 552 GuideWest(GuideEW[1].value); 363 553 } … … 365 555 GuideEW[0].value=0; 366 556 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 } 383 562 384 563 } … … 391 570 { 392 571 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; 413 588 } 414 589 return true; 415 590 } 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; 425 604 } 426 605 return true; 427 606 } 428 607 429 if(strcmp(name,GuiderVideoSV.name)==0) { 608 if(strcmp(name,PrimaryCCD.FrameTypeSP->name)==0) 609 { 430 610 // 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 } 458 621 } 459 622 … … 475 638 return -1; 476 639 } 640 641 bool INDI::CCD::AbortExposure() 642 { 643 IDLog("INDI::CCD::AbortExposure - Should never get here\n"); 644 return false; 645 } 646 647 bool 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 653 bool 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 659 void INDI::CCD::addFITSKeywords(fitsfile *fptr) 660 { 661 // Nothing to do here. HW layer should take care of it if needed. 662 } 663 477 664 bool INDI::CCD::ExposureComplete() 478 665 { … … 482 669 long naxes[2]; 483 670 long naxis=2; 671 int numbytes=0; 484 672 485 673 fitsfile *fptr=NULL; 486 674 487 488 675 //IDLog("Enter Exposure Complete %d %d %d %d\n",SubW,SubH,BinX,BinY); 489 676 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 493 682 // Now we have to send fits format data to the client 494 683 memsize=5760; 495 684 memptr=malloc(memsize); 496 if(!memptr) { 685 if(!memptr) 686 { 497 687 IDLog("Error: failed to allocate memory: %lu\n",(unsigned long)memsize); 498 688 } 689 499 690 fits_create_memfile(&fptr,&memptr,&memsize,2880,realloc,&status); 500 if(status) { 691 692 if(status) 693 { 501 694 IDLog("Error: Failed to create FITS image\n"); 502 695 fits_report_error(stderr, status); /* print out any error messages */ 503 696 return false; 504 697 } 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 { 508 703 IDLog("Error: Failed to create FITS image\n"); 509 704 fits_report_error(stderr, status); /* print out any error messages */ 510 705 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 514 712 if (status) 515 713 { 516 714 IDLog("Error: Failed to write FITS image\n"); 517 715 fits_report_error(stderr, status); /* print out any error messages */ 518 716 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); 533 724 534 725 uploadfile(memptr,memsize); … … 539 730 bool INDI::CCD::GuideExposureComplete() 540 731 { 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 guider546 // is on, then send this as a video stream547 // frame, and, start another frame548 549 // Ok, bit of a kludge here550 // we need to send a new size to kstars551 //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 streaming568 // So, lets send this as an 8 bit fits frame569 732 void *memptr; 570 733 size_t memsize; … … 574 737 575 738 fitsfile *fptr=NULL; 576 naxes[0]=G SubW;577 naxes[1]=G SubH;739 naxes[0]=GuideCCD.getSubW(); 740 naxes[1]=GuideCCD.getSubH(); 578 741 // Now we have to send fits format data to the client 579 742 memsize=5760; 580 743 memptr=malloc(memsize); 581 if(!memptr) { 744 if(!memptr) 745 { 582 746 IDLog("Error: failed to allocate memory: %lu\n",(unsigned long)memsize); 583 747 } 584 748 fits_create_memfile(&fptr,&memptr,&memsize,2880,realloc,&status); 585 if(status) { 749 if(status) 750 { 586 751 IDLog("Error: Failed to create FITS image\n"); 587 752 fits_report_error(stderr, status); /* print out any error messages */ … … 596 761 } 597 762 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); 599 764 if (status) 600 765 { … … 605 770 fits_close_file(fptr,&status); 606 771 IDLog("Built the Guider fits file\n"); 607 Guide rExposureNV.s=IPS_OK;608 IDSetNumber( &GuiderExposureNV,NULL);609 610 IDLog("Sending guider fits file via %s\n",Guide rBV.name);611 Guide rB.blob=memptr;612 Guide rB.bloblen=memsize;613 Guide rB.size=memsize;614 strcpy(Guide rB.format,".fits");615 Guide rBV.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); 617 782 free(memptr); 618 }619 620 783 621 784 return true; … … 623 786 624 787 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; 788 int 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); 634 798 635 799 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 802 void 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 812 void INDI::CCD::SetGuidHeadParams(int x,int y,int bpp,float xf,float yf) 712 813 { 713 814 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 729 822 } 730 823 … … 734 827 } 735 828 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 830 bool INDI::CCD::GuideNorth(float ms) 831 { 832 return false; 833 } 834 bool INDI::CCD::GuideSouth(float ms) 835 { 836 return false; 837 } 838 bool INDI::CCD::GuideEast(float ms) 839 { 840 return false; 841 } 842 bool INDI::CCD::GuideWest(float ms) 843 { 844 return false; 845 } 846 -
BAORadio/libindi/libindi/libs/indibase/indiccd.h
r504 r642 1 1 /******************************************************************************* 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. 20 17 *******************************************************************************/ 18 21 19 22 20 #ifndef INDI_CCD_H 23 21 #define INDI_CCD_H 24 22 23 #include <fitsio.h> 24 25 25 #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 28 extern const char *IMAGE_SETTINGS_TAB; 29 extern const char *IMAGE_INFO_TAB; 30 extern const char *GUIDE_HEAD_TAB; 31 extern const char *GUIDE_CONTROL_TAB; 32 33 class CCDChip 33 34 { 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 36 public: 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 72 private: 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 */ 124 class INDI::CCD : public INDI::DefaultDriver, INDI::GuiderInterface 125 { 126 public: 77 127 CCD(); 78 128 virtual ~CCD(); 79 129 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(); 135 131 virtual bool updateProperties(); 136 132 virtual void ISGetProperties (const char *dev); 137 138 133 virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n); 139 134 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 */ 144 144 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 */ 145 149 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 */ 146 162 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 */ 147 168 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 */ 148 173 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); 162 261 163 262 }; -
BAORadio/libindi/libindi/libs/indibase/indidevice.cpp
r504 r642 299 299 // We dont actually implement a device here 300 300 // So we cannot connect to it 301 IDLog("IndiDevice Connect, we should never get here\n"); 301 302 IDMessage(deviceName(),"IndiDevice:: has no device attached...."); 302 303 return false; -
BAORadio/libindi/libindi/libs/indibase/indifilterwheel.cpp
r504 r642 1 1 /******************************************************************************* 2 Copyright(c) 2010 Gerry Rozema. All rights reserved.2 Copyright(c) 2010, 2011 Gerry Rozema. All rights reserved. 3 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. 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. 8 7 9 This program is distributed in the hope that it will be useful, but WITHOUT10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for12 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. 13 12 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. 20 17 *******************************************************************************/ 21 18 … … 27 24 { 28 25 //ctor 29 MaxFilter= 12;26 MaxFilter=-1; 30 27 } 31 28 … … 35 32 } 36 33 34 37 35 bool INDI::FilterWheel::initProperties() 38 36 { 39 DefaultDriver::initProperties(); // let the base class flesh in what it wants37 DefaultDriver::initProperties(); 40 38 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); 59 40 } 60 41 … … 66 47 if(isConnected()) 67 48 { 68 defineNumber(&FilterSlotNV); 69 defineText(&FilterNameTV); 49 defineNumber(FilterSlotNP); 50 51 if (GetFilterNames(deviceName(), FILTER_TAB)) 52 defineText(FilterNameTP); 70 53 } 71 54 return; … … 79 62 if(isConnected()) 80 63 { 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); 86 68 } else 87 69 { 88 deleteProperty(FilterSlotN V.name);89 deleteProperty(FilterNameT V.name);70 deleteProperty(FilterSlotNP->name); 71 deleteProperty(FilterNameTP->name); 90 72 } 91 73 92 74 return true; 75 } 76 77 bool 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); 93 80 } 94 81 … … 97 84 // first check if it's for our device 98 85 //IDLog("INDI::FilterWheel::ISNewNumber %s\n",name); 99 if(strcmp(dev,deviceName())==0) { 86 if(strcmp(dev,deviceName())==0) 87 { 100 88 // This is for our device 101 89 // Now lets see if it's something we process here 102 90 103 if(strcmp(name,"FILTER_SLOT")==0) {104 91 if(strcmp(name,"FILTER_SLOT")==0) 92 { 105 93 int f; 106 94 107 95 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 { 110 100 // This is the new filter number we are being asked 111 101 // to set as active … … 114 104 } 115 105 116 if(f != -1) { 106 if(f != -1) 107 { 117 108 //IDLog("Filter wheel got a filter slot change\n"); 118 109 // tell the client we are busy changing the filter 119 FilterSlotN V.s=IPS_BUSY;120 IDSetNumber( &FilterSlotNV,NULL);110 FilterSlotNP->s=IPS_BUSY; 111 IDSetNumber(FilterSlotNP,NULL); 121 112 // Tell the hardware to change 122 113 SelectFilter(f); … … 136 127 //IDLog("INDI::FilterWheel got %d new text items name %s\n",n,name); 137 128 // first check if it's for our device 138 if(strcmp(dev,deviceName())==0) { 129 if(strcmp(dev,deviceName())==0) 130 { 139 131 // This is for our device 140 132 // 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 { 154 135 int rc; 155 136 //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); 162 139 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 } 163 147 // We processed this one, so, tell the world we did it 164 148 return true; … … 170 154 } 171 155 172 int INDI::FilterWheel::SelectFilterDone(int f)173 {174 // The hardware has finished changing175 // filters176 FilterSlotN[0].value=f;177 FilterSlotNV.s=IPS_OK;178 // Tell the clients we are done, and179 // filter is now useable180 IDSetNumber(&FilterSlotNV,NULL);181 return 0;182 }183 184 int INDI::FilterWheel::SelectFilter(int)185 {186 return -1;187 }188 189 156 int INDI::FilterWheel::QueryFilter() 190 157 { … … 193 160 194 161 162 bool INDI::FilterWheel::SelectFilter(int) 163 { 164 return false; 165 } 166 167 bool INDI::FilterWheel::SetFilterNames() 168 { 169 return true; 170 } 171 172 void INDI::FilterWheel::ISSnoopDevice (XMLEle *root) 173 { 174 return; 175 } 176 177 178 bool 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 1 1 /******************************************************************************* 2 Copyright(c) 2010 Gerry Rozema. All rights reserved.2 Copyright(c) 2010, 2011 Gerry Rozema. All rights reserved. 3 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. 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. 8 7 9 This program is distributed in the hope that it will be useful, but WITHOUT10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for12 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. 13 12 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 *******************************************************************************/ 17 18 18 The full GNU General Public License is included in this distribution in the19 file called LICENSE.20 *******************************************************************************/21 19 #ifndef INDI_FILTERWHEEL_H 22 20 #define INDI_FILTERWHEEL_H 23 21 24 22 #include "defaultdriver.h" 23 #include "indifilterinterface.h" 25 24 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 */ 34 class INDI::FilterWheel: public INDI::DefaultDriver, public INDI::FilterInterface 27 35 { 28 protected: 29 private: 36 protected: 30 37 31 public: 32 FilterWheel(); 33 virtual ~FilterWheel(); 38 FilterWheel(); 39 virtual ~FilterWheel(); 34 40 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 41 public: 46 42 47 43 virtual bool initProperties(); 48 44 virtual bool updateProperties(); 49 45 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); 50 50 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: 57 52 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); 63 57 64 58 }; -
BAORadio/libindi/libindi/libs/indibase/indifocuser.cpp
r504 r642 1 1 /******************************************************************************* 2 Copyright(c) 201 0Gerry Rozema. All rights reserved.2 Copyright(c) 2011 Gerry Rozema. All rights reserved. 3 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. 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. 8 7 9 This program is distributed in the hope that it will be useful, but WITHOUT10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for12 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. 13 12 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 *******************************************************************************/ 17 18 18 The full GNU General Public License is included in this distribution in the19 file called LICENSE.20 *******************************************************************************/21 19 #include "indifocuser.h" 22 20 … … 25 23 INDI::Focuser::Focuser() 26 24 { 27 //ctor 25 FocusSpeedNP = new INumberVectorProperty; 26 FocusTimerNP = new INumberVectorProperty; 27 FocusMotionSP = new ISwitchVectorProperty; 28 28 } 29 29 30 30 INDI::Focuser::~Focuser() 31 31 { 32 //dtor 32 delete FocusSpeedNP; 33 delete FocusTimerNP; 34 delete FocusMotionSP; 35 33 36 } 34 37 … … 37 40 DefaultDriver::initProperties(); // let the base class flesh in what it wants 38 41 39 IUFillNumber(&Focus speedN[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); 41 44 42 IUFillNumber(&Focus timerN[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); 44 47 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); 49 51 50 52 return 0; … … 54 56 { 55 57 // First we let our parent populate 56 IDLog("INDI::Focuser::ISGetProperties %s\n",dev);57 58 DefaultDriver::ISGetProperties(dev); 58 59 … … 65 66 { 66 67 // 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); 70 71 } else 71 72 { 72 deleteProperty(Focus motionSV.name);73 deleteProperty(Focus speedNV.name);74 deleteProperty(Focus timerNV.name);73 deleteProperty(FocusMotionSP->name); 74 deleteProperty(FocusSpeedNP->name); 75 deleteProperty(FocusTimerNP->name); 75 76 } 76 77 return true; … … 81 82 { 82 83 // 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 { 85 86 // This is for our device 86 87 // 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 { 88 90 // Ok, gotta move the focusser now 89 intdir;91 FocusDirection dir; 90 92 int speed; 91 93 int t; … … 93 95 //IDLog(") 94 96 // first we get all the numbers just sent to us 95 Focus timerNV.s=IPS_OK;96 IUUpdateNumber( &FocustimerNV,values,names,n);97 FocusTimerNP->s=IPS_OK; 98 IUUpdateNumber(FocusTimerNP,values,names,n); 97 99 98 100 // Now lets find what we need for this move 99 speed=Focus speedN[0].value;100 if(Focus motionS[0].s==ISS_ON) dir=1;101 else dir= 0;102 t=Focus timerN[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; 103 105 104 Move(dir,speed,t); 106 if (Move(dir,speed,t) == false) 107 FocusTimerNP->s = IPS_ALERT; 105 108 106 107 // Update client display 108 IDSetNumber(&FocustimerNV,NULL); 109 IDSetNumber(FocusTimerNP,NULL); 109 110 return true; 110 111 } 111 112 112 113 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); 118 118 119 119 120 120 121 121 // Update client display 122 IDSetNumber( &FocusspeedNV,NULL);122 IDSetNumber(FocusSpeedNP,NULL); 123 123 return true; 124 124 } … … 132 132 bool INDI::Focuser::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) 133 133 { 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 //}138 134 139 if(strcmp(dev,deviceName())==0) { 135 if(strcmp(dev,deviceName())==0) 136 { 140 137 // This one is for us 141 if(strcmp(name,"FOCUS_MOTION")==0) { 138 if(strcmp(name,"FOCUS_MOTION")==0) 139 { 142 140 // client is telling us what to do with focus direction 143 Focus motionSV.s=IPS_OK;144 IUUpdateSwitch( &FocusmotionSV,states,names,n);141 FocusMotionSP->s=IPS_OK; 142 IUUpdateSwitch(FocusMotionSP,states,names,n); 145 143 // Update client display 146 IDSetSwitch( &FocusmotionSV,NULL);144 IDSetSwitch(FocusMotionSP,NULL); 147 145 148 146 return true; … … 155 153 } 156 154 157 int INDI::Focuser::Move(int,int,int) 155 bool 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 160 void INDI::Focuser::ISSnoopDevice (XMLEle *root) 161 { 162 return; 163 } 164 165 bool INDI::Focuser::Move(FocusDirection dir, int speed, int duration) 158 166 { 159 167 // This should be a virtual function, because the low level hardware class … … 161 169 // but it's much easier early development if the method actually 162 170 // exists for now 163 return -1;171 return false; 164 172 } 165 173 -
BAORadio/libindi/libindi/libs/indibase/indifocuser.h
r504 r642 1 1 /******************************************************************************* 2 Copyright(c) 201 0Gerry Rozema. All rights reserved.2 Copyright(c) 2011 Gerry Rozema. All rights reserved. 3 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. 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. 8 7 9 This program is distributed in the hope that it will be useful, but WITHOUT10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for12 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. 13 12 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. 20 17 *******************************************************************************/ 21 18 … … 25 22 #include "defaultdriver.h" 26 23 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 */ 27 32 class INDI::Focuser : public INDI::DefaultDriver 28 33 { 29 30 protected:31 private:32 33 34 public: 34 35 Focuser(); 35 36 virtual ~Focuser(); 36 37 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 }; 44 39 45 40 virtual bool initProperties(); 46 41 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(); 53 43 virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n); 54 44 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); 55 47 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]; 58 64 59 65 }; -
BAORadio/libindi/libindi/libs/indibase/inditelescope.cpp
r504 r642 1 1 /******************************************************************************* 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. 20 17 *******************************************************************************/ 18 21 19 22 20 #include "inditelescope.h" … … 39 37 { 40 38 //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 41 49 } 42 50 43 51 INDI::Telescope::~Telescope() 44 52 { 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; 46 62 } 47 63 … … 49 65 { 50 66 DefaultDriver::initProperties(); 51 52 EqNV = new INumberVectorProperty;53 67 54 68 IUFillNumber(&EqN[0],"RA","RA (hh:mm:ss)","%010.6m",0,24,0,0); 55 69 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); 59 71 60 72 IUFillNumber(&EqReqN[0],"RA","RA (hh:mm:ss)","%010.6m",0,24,0,0); 61 73 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); 65 75 66 76 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); 71 79 72 80 IUFillSwitch(&CoordS[0],"TRACK","Track",ISS_OFF); 73 81 IUFillSwitch(&CoordS[1],"SLEW","Slew",ISS_OFF); 74 82 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 78 90 79 91 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); 83 93 84 94 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); 86 104 87 105 TrackState=SCOPE_PARKED; … … 96 114 97 115 // We may need the port set before we can connect 98 //IDDefText(&PortTV,NULL);116 IDDefText(PortTV,NULL); 99 117 //LoadConfig(); 100 118 … … 107 125 defineNumber(LocationNV); 108 126 defineSwitch(ParkSV); 127 defineSwitch(MovementNSSP); 128 defineSwitch(MovementWESP); 129 defineSwitch(ConfigSV); 130 109 131 } 110 132 return; … … 113 135 bool INDI::Telescope::updateProperties() 114 136 { 137 defineText(PortTV); 115 138 if(isConnected()) 116 139 { 117 140 // Now we add our telescope specific stuff 118 //IDLog("INDI::Telescope adding properties\n");119 141 defineSwitch(CoordSV); 120 142 defineNumber(EqNV); 121 143 defineNumber(EqReqNV); 122 //IDDefText(&PortTV,NULL); 144 defineSwitch(MovementNSSP); 145 defineSwitch(MovementWESP); 123 146 defineNumber(LocationNV); 124 147 defineSwitch(ParkSV); 148 125 149 } else 126 150 { … … 129 153 deleteProperty(EqNV->name); 130 154 deleteProperty(EqReqNV->name); 131 //DeleteProperty(PortTV.name); 155 deleteProperty(MovementNSSP->name); 156 deleteProperty(MovementWESP->name); 132 157 deleteProperty(LocationNV->name); 133 158 deleteProperty(ParkSV->name); 134 159 135 initProperties(); 136 } 160 //initProperties(); 161 } 162 defineSwitch(ConfigSV); 163 137 164 return true; 138 165 } 139 166 140 int INDI::Telescope::NewRaDec(double ra,double dec) 167 bool INDI::Telescope::saveConfigItems(FILE *fp) 168 { 169 170 IUSaveConfigNumber(fp,LocationNV); 171 return true; 172 } 173 174 void INDI::Telescope::NewRaDec(double ra,double dec) 141 175 { 142 176 // Lets set our eq values to these numbers 143 177 // which came from the hardware 144 EqN[0].value=ra; 145 EqN[1].value=dec; 178 static int last_state=-1; 146 179 147 180 if (TrackState == SCOPE_TRACKING && EqReqNV->s != IPS_OK) … … 150 183 IDSetNumber(EqReqNV, NULL); 151 184 } 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) 153 186 { 154 187 EqReqNV->s = IPS_IDLE; … … 156 189 } 157 190 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 159 201 } 160 202 … … 176 218 // if we get here, our mount doesn't support sync 177 219 IDMessage(deviceName(),"Mount does not support Sync"); 220 return false; 221 } 222 223 bool 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 232 bool 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); 178 238 return false; 179 239 } … … 328 388 Park(); 329 389 } 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 330 419 } 331 420 … … 334 423 } 335 424 425 336 426 bool INDI::Telescope::Connect() 337 427 { 338 428 // 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); 340 431 bool rc=false; 341 432 342 433 if(isConnected()) return true; 343 434 344 //IDLog("Calling Connect\n"); 435 436 if (isDebug()) 437 IDLog("Telescope Calling Connect\n"); 345 438 346 439 rc=Connect(PortT[0].text); 440 441 if (isDebug()) 442 IDLog("Telescope Connect returns %d\n",rc); 347 443 348 444 if(rc) … … 351 447 } 352 448 449 353 450 bool INDI::Telescope::Connect(const char *port) 354 451 { … … 361 458 bool rc; 362 459 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) 365 463 { 366 464 tty_error_msg(connectrc, errorMsg, MAXRBUF); 367 465 368 if (isDebug())466 //if (isDebug()) 369 467 IDLog("Failed to connect o port %s. Error: %s", port, errorMsg); 370 468 IDMessage(deviceName(), "Failed to connect to port %s. Error: %s", port, errorMsg); … … 373 471 374 472 } 375 473 IDLog("Port Fd %d\n",PortFD); 376 474 /* Flush the input (read) buffer */ 377 475 378 tcflush(PortFD,TCIOFLUSH);476 //tcflush(PortFD,TCIOFLUSH); 379 477 380 478 /* Test connection */ … … 401 499 //Connected=false; 402 500 501 IDLog("IndiTelescope Disconnect\n"); 502 403 503 close(PortFD); 404 504 IDMessage(deviceName(),"Telescope is offline."); … … 410 510 void INDI::Telescope::TimerHit() 411 511 { 412 //IDLog("T imer Hit\n");512 //IDLog("Telescope Timer Hit\n"); 413 513 if(isConnected()) 414 514 { … … 417 517 rc=ReadScopeStatus(); 418 518 //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) 439 520 { 440 521 // read was not good 441 522 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 446 526 SetTimer(POLLMS); 447 527 } -
BAORadio/libindi/libindi/libs/indibase/inditelescope.h
r504 r642 1 1 /******************************************************************************* 2 Copyright(c) 201 0 Gerry Rozema. All rights reserved.2 Copyright(c) 2011 Gerry Rozema, Jasem Mutlaq. All rights reserved. 3 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. 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. 8 7 9 This program is distributed in the hope that it will be useful, but WITHOUT10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for12 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. 13 12 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. 20 17 *******************************************************************************/ 21 18 … … 25 22 #include "defaultdriver.h" 26 23 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 */ 27 44 class INDI::Telescope : public INDI::DefaultDriver 28 45 { 29 protected:30 //bool Connected;31 32 46 private: 33 47 … … 37 51 38 52 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; 39 145 40 146 // All telescopes should produce equatorial co-ordinates … … 49 155 ISwitch CoordS[3]; // On a coord_set message, sync, or slew 50 156 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 51 160 INumberVectorProperty *LocationNV; // A number vector that stores lattitude and longitude 52 161 INumber LocationN[2]; … … 55 164 ISwitch ParkS[1]; 56 165 57 // I dont know of any telescopes that dont58 // need a port for connection59 // So lets put all the port connect framework60 // into our generic telescope super class61 166 ITextVectorProperty *PortTV; // A text vector that stores out physical port name 62 167 IText PortT[1]; 63 168 169 ISwitch MovementNSS[2]; // A switch for North/South motion 170 ISwitchVectorProperty *MovementNSSP; 64 171 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; 73 174 74 // overrides of base class virtual functions75 // that are specific to our way of implementing Indi76 virtual bool initProperties(); // Called to initialize basic properties required all the time77 virtual bool updateProperties(); // Called when connected state changes, to add/remove properties78 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 control87 // We put the serial helper into the base telescope class88 // One less piece to worry about in the hardware specific89 // low level stuff90 int PortFD;91 92 93 // This is a variable filled in by the ReadStatus telescope94 // low level code, used to report current state95 // are we slewing, tracking, or parked.96 int TrackState;97 98 99 // These functions are telescope specific100 // and meant to make life really easy for deriving101 // hardware specific telescope classes102 int NewRaDec(double,double); // The child class will call this when it has updates103 104 105 // And these are the hardware specific functions our children need to override106 // They are not pure virtual, because, not all functions are relavent for all types107 // of mount, ie, a Goto is not relavent for a Push-to mount108 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();122 175 123 176 }; -
BAORadio/libindi/libindi/libs/indibase/indiusbdevice.cpp
r504 r642 1 1 /******************************************************************************* 2 Copyright(c) 201 0Gerry Rozema. All rights reserved.2 Copyright(c) 2011 Gerry Rozema. All rights reserved. 3 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. 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. 8 7 9 This program is distributed in the hope that it will be useful, but WITHOUT10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for12 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. 13 12 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. 20 17 *******************************************************************************/ 21 18 #include "indiusbdevice.h" … … 149 146 } 150 147 151 int INDI::USBDevice::ReadBulk(char *buf,int c,int timeout)148 int INDI::USBDevice::ReadBulk(char *buf,int nbytes,int timeout) 152 149 { 153 150 int rc; 154 151 155 152 //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); 157 154 return rc; 158 155 159 156 } 160 157 161 int INDI::USBDevice::WriteBulk(char *buf,int c,int timeout)158 int INDI::USBDevice::WriteBulk(char *buf,int nbytes,int timeout) 162 159 { 163 160 int rc; … … 165 162 //printf("Writing %02x to endpoint %d\n",buf[0],OutputEndpoint); 166 163 //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); 168 165 return rc; 169 166 -
BAORadio/libindi/libindi/libs/indibase/indiusbdevice.h
r504 r642 1 1 /******************************************************************************* 2 Copyright(c) 201 0Gerry Rozema. All rights reserved.2 Copyright(c) 2011 Gerry Rozema. All rights reserved. 3 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. 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. 8 7 9 This program is distributed in the hope that it will be useful, but WITHOUT10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for12 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. 13 12 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. 20 17 *******************************************************************************/ 21 18 … … 34 31 #include "indibase.h" 35 32 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 */ 36 42 class INDI::USBDevice 37 43 { … … 56 62 int ControlMessage(); 57 63 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); 60 66 int FindEndpoints(); 61 67 int Open(); -
BAORadio/libindi/libindi/libs/indicom.c
r504 r642 147 147 default: 148 148 printf ("fs_sexa: unknown fracbase: %d\n", fracbase); 149 exit(1);149 return -1; 150 150 } 151 151 … … 389 389 } 390 390 391 #if def BSD391 #if defined(BSD) && !defined(__GNU__) 392 392 // BSD - OSX version 393 393 int tty_connect(const char *device, int bit_rate, int word_size, int parity, int stop_bits, int *fd) … … 949 949 default: 950 950 fprintf (stderr, "Impossible IPState %d\n", s); 951 exit(1);951 return NULL; 952 952 } 953 953 } … … 1007 1007 default: 1008 1008 fprintf (stderr, "Impossible ISState %d\n", s); 1009 return NULL; 1009 1010 } 1010 1011 } … … 1020 1021 default: 1021 1022 fprintf (stderr, "Impossible ISRule %d\n", r); 1023 return NULL; 1022 1024 } 1023 1025 } … … 1033 1035 default: 1034 1036 fprintf (stderr, "Impossible IPerm %d\n", p); 1037 return NULL; 1035 1038 } 1036 1039 } -
BAORadio/libindi/libindi/libs/lilxml.c
r490 r642 15 15 You should have received a copy of the GNU Lesser General Public 16 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 5 1 Franklin Street, Fifth Floor, Boston, MA 02110-1301USA17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 18 19 19 #endif … … 27 27 */ 28 28 29 #include <stdio.h> 29 30 #include <stdlib.h> 30 31 #include <string.h> … … 41 42 #define MINMEM 64 /* starting string length */ 42 43 43 static int oneXMLchar (LilXML *lp, int c, char errmsg[]);44 static int oneXMLchar (LilXML *lp, int c, char ynot[]); 44 45 static void initParser(LilXML *lp); 45 46 static void pushXMLEle(LilXML *lp); … … 111 112 static char entities[] = "&<>'\""; 112 113 113 /* default memory managers, override with indi_xmlMalloc() */114 /* default memory managers, override with lilxmlMalloc() */ 114 115 static void *(*mymalloc)(size_t size) = malloc; 115 116 static void *(*myrealloc)(void *ptr, size_t size) = realloc; … … 120 121 */ 121 122 void 122 indi_xmlMalloc (void *(*newmalloc)(size_t size),123 124 125 { 126 127 128 123 lilxmlMalloc (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; 129 130 } 130 131 … … 133 134 newLilXML () 134 135 { 135 136 137 138 136 LilXML *lp = (LilXML *) moremem (NULL, sizeof(LilXML)); 137 memset (lp, 0, sizeof(LilXML)); 138 initParser(lp); 139 return (lp); 139 140 } 140 141 … … 143 144 delLilXML (LilXML *lp) 144 145 { 145 146 147 146 delXMLEle (lp->ce); 147 freeString (&lp->endtag); 148 (*myfree) (lp); 148 149 } 149 150 … … 152 153 delXMLEle (XMLEle *ep) 153 154 { 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 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); 192 193 } 193 194 194 195 /* process one more character of an XML file. 195 196 * 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'. 198 199 * N.B. it is up to the caller to delete any tree returned with delXMLEle(). 199 200 */ 200 201 XMLEle * 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); 202 readXMLEle (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 */ 270 XMLEle * 271 parseXML (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 */ 287 XMLEle * 288 cloneXMLEle (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); 264 300 } 265 301 … … 270 306 findXMLAtt (XMLEle *ep, const char *name) 271 307 { 272 273 274 275 276 277 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); 278 314 } 279 315 … … 284 320 findXMLEle (XMLEle *ep, const char *tag) 285 321 { 286 287 288 289 290 291 292 293 294 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); 295 331 } 296 332 … … 302 338 nextXMLEle (XMLEle *ep, int init) 303 339 { 304 305 306 307 308 309 310 311 312 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]); 313 349 } 314 350 … … 320 356 nextXMLAtt (XMLEle *ep, int init) 321 357 { 322 323 324 325 326 327 328 329 330 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]); 331 367 } 332 368 … … 335 371 parentXMLEle (XMLEle *ep) 336 372 { 337 373 return (ep->pe); 338 374 } 339 375 … … 342 378 parentXMLAtt (XMLAtt *ap) 343 379 { 344 380 return (ap->ce); 345 381 } 346 382 … … 351 387 tagXMLEle (XMLEle *ep) 352 388 { 353 389 return (ep->tag.s); 354 390 } 355 391 … … 358 394 pcdataXMLEle (XMLEle *ep) 359 395 { 360 396 return (ep->pcdata.s); 361 397 } 362 398 363 399 /* return the number of characters in the pcdata portion of the given element */ 364 int 400 int 365 401 pcdatalenXMLEle (XMLEle *ep) 366 402 { 367 403 return (ep->pcdata.sl); 368 404 } 369 405 … … 372 408 nameXMLAtt (XMLAtt *ap) 373 409 { 374 410 return (ap->name.s); 375 411 } 376 412 … … 379 415 valuXMLAtt (XMLAtt *ap) 380 416 { 381 417 return (ap->valu.s); 382 418 } 383 419 … … 386 422 nXMLEle (XMLEle *ep) 387 423 { 388 424 return (ep->nel); 389 425 } 390 426 … … 393 429 nXMLAtt (XMLEle *ep) 394 430 { 395 431 return (ep->nat); 396 432 } 397 433 … … 403 439 findXMLAttValu (XMLEle *ep, const char *name) 404 440 { 405 406 441 XMLAtt *a = findXMLAtt (ep, name); 442 return (a ? a->valu.s : ""); 407 443 } 408 444 409 445 /* 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[] 411 447 */ 412 448 XMLEle * 413 readXMLFile (FILE *fp, LilXML *lp, char errmsg[])414 { 415 416 417 418 XMLEle *root = readXMLEle (lp, c, errmsg);419 if (root || errmsg[0])420 421 422 423 449 readXMLFile (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); 424 460 } 425 461 … … 430 466 addXMLEle (XMLEle *parent, const char *tag) 431 467 { 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 */ 476 void 477 appXMLEle (XMLEle *ep, XMLEle *newep) 478 { 479 ep->el = (XMLEle **) moremem (ep->el, (ep->nel+1)*sizeof(XMLEle *)); 480 ep->el[ep->nel++] = newep; 435 481 } 436 482 … … 439 485 editXMLEle (XMLEle *ep, const char *pcdata) 440 486 { 441 442 443 487 freeString (&ep->pcdata); 488 appendString (&ep->pcdata, pcdata); 489 ep->pcdata_hasent = (strpbrk (pcdata, entities) != NULL); 444 490 } 445 491 … … 448 494 addXMLAtt (XMLEle *ep, const char *name, const char *valu) 449 495 { 450 451 452 453 496 XMLAtt *ap = growAtt (ep); 497 appendString (&ap->name, name); 498 appendString (&ap->valu, valu); 499 return (ap); 454 500 } 455 501 … … 458 504 rmXMLAtt (XMLEle *ep, const char *name) 459 505 { 460 461 462 463 464 465 466 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 } 469 515 } 470 516 … … 473 519 editXMLAtt (XMLAtt *ap, const char *str) 474 520 { 475 476 521 freeString (&ap->valu); 522 appendString (&ap->valu, str); 477 523 } 478 524 … … 484 530 prXMLEle (FILE *fp, XMLEle *ep, int level) 485 531 { 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 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"); 512 558 } 513 559 … … 520 566 sprXMLEle (char *s, XMLEle *ep, int level) 521 567 { 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 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); 553 599 } 554 600 … … 560 606 sprlXMLEle (XMLEle *ep, int level) 561 607 { 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 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); 591 637 } 592 638 … … 598 644 entityXML (char *s) 599 645 { 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, "&"); 618 break; 619 case '<': 620 nmalbuf += sprintf (malbuf+nmalbuf, "<"); 621 break; 622 case '>': 623 nmalbuf += sprintf (malbuf+nmalbuf, ">"); 624 break; 625 case '\'': 626 nmalbuf += sprintf (malbuf+nmalbuf, "'"); 627 break; 628 case '"': 629 nmalbuf += sprintf (malbuf+nmalbuf, """); 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, "&"); 664 break; 665 case '<': 666 nmalbuf += sprintf (malbuf+nmalbuf, "<"); 667 break; 668 case '>': 669 nmalbuf += sprintf (malbuf+nmalbuf, ">"); 670 break; 671 case '\'': 672 nmalbuf += sprintf (malbuf+nmalbuf, "'"); 673 break; 674 case '"': 675 nmalbuf += sprintf (malbuf+nmalbuf, """); 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 652 701 653 702 /* if ent is a recognized xml entity sequence, set *cp to char and return 1 … … 657 706 decodeEntity (char *ent, int *cp) 658 707 { 659 660 constchar *ent;661 662 663 664 665 666 667 668 669 unsignedint i;670 671 672 673 674 675 676 677 678 708 static struct { 709 char *ent; 710 char c; 711 } enttable[] = { 712 {"&", '&'}, 713 {"'", '\''}, 714 {"<", '<'}, 715 {">", '>'}, 716 {""", '"'}, 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); 679 728 } 680 729 … … 682 731 * if find final closure, return 1 and tree is in ce. 683 732 * 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. 685 734 */ 686 735 static int 687 oneXMLchar (LilXML *lp, int c, char errmsg[])688 { 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 sprintf (errmsg, "Line %d: Bogus tag char %c", lp->ln, c);704 705 706 707 708 709 710 711 712 713 714 715 else 716 717 718 719 720 721 722 723 724 725 726 727 728 729 sprintf (errmsg, "Line %d: Bogus leading attr name char: %c",730 731 732 733 734 735 736 737 738 739 740 741 742 sprintf (errmsg, "Line %d: Bogus char %c before >", lp->ln, c);743 744 745 746 747 748 749 750 751 752 753 sprintf (errmsg, "Line %d: Bogus attr name char: %c", lp->ln,c);754 755 756 757 758 759 760 761 762 763 sprintf (errmsg, "Line %d: No value for attribute %s", lp->ln,764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 sprintf (errmsg, "Line %d: Bogus preend tag char %c", lp->ln,c);855 856 857 858 859 860 861 862 863 864 sprintf (errmsg,"Line %d: closing tag %s does not match %s",865 866 867 868 869 870 871 872 873 sprintf (errmsg, "Line %d: Bogus end tag char %c", lp->ln, c);874 875 876 877 878 879 736 oneXMLchar (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); 880 929 } 881 930 … … 884 933 initParser(LilXML *lp) 885 934 { 886 887 888 889 890 891 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; 892 941 } 893 942 … … 900 949 pushXMLEle(LilXML *lp) 901 950 { 902 903 951 lp->ce = growEle (lp->ce); 952 resetEndTag(lp); 904 953 } 905 954 … … 910 959 popXMLEle(LilXML *lp) 911 960 { 912 913 961 lp->ce = lp->ce->pe; 962 resetEndTag(lp); 914 963 } 915 964 … … 918 967 growEle (XMLEle *pe) 919 968 { 920 921 922 923 924 925 926 927 928 929 930 931 932 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); 933 982 } 934 983 … … 937 986 growAtt(XMLEle *ep) 938 987 { 939 940 941 942 943 944 945 946 947 948 949 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); 950 999 } 951 1000 … … 954 1003 freeAtt (XMLAtt *a) 955 1004 { 956 957 958 959 960 1005 if (!a) 1006 return; 1007 freeString (&a->name); 1008 freeString (&a->valu); 1009 (*myfree)(a); 961 1010 } 962 1011 … … 965 1014 resetEndTag(LilXML *lp) 966 1015 { 967 968 1016 freeString (&lp->endtag); 1017 newString (&lp->endtag); 969 1018 } 970 1019 … … 975 1024 isTokenChar (int start, int c) 976 1025 { 977 1026 return (isalpha(c) || c == '_' || (!start && isdigit(c))); 978 1027 } 979 1028 … … 982 1031 growString (String *sp, int c) 983 1032 { 984 985 986 987 988 989 990 991 992 993 994 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++; 995 1044 } 996 1045 … … 999 1048 appendString (String *sp, const char *str) 1000 1049 { 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 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; 1012 1061 } 1013 1062 … … 1016 1065 newString(String *sp) 1017 1066 { 1018 1019 1020 1021 1067 sp->s = (char *)moremem(NULL, MINMEM); 1068 sp->sm = MINMEM; 1069 *sp->s = '\0'; 1070 sp->sl = 0; 1022 1071 } 1023 1072 … … 1026 1075 freeString (String *sp) 1027 1076 { 1028 1029 1030 1031 1032 1077 if (sp->s) 1078 (*myfree) (sp->s); 1079 sp->s = NULL; 1080 sp->sl = 0; 1081 sp->sm = 0; 1033 1082 } 1034 1083 … … 1037 1086 moremem (void *old, int n) 1038 1087 { 1039 1088 return (old ? (*myrealloc)(old, n) : (*mymalloc)(n)); 1040 1089 } 1041 1090 … … 1044 1093 main (int ac, char *av[]) 1045 1094 { 1046 1047 char errmsg[1024];1048 1049 1050 root = readXMLFile (stdin, lp, errmsg);1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 } else if (errmsg[0]) {1072 fprintf (stderr, "Error: %s\n", errmsg);1073 1074 1075 1076 1077 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); 1078 1127 } 1079 1128 #endif 1080 -
BAORadio/libindi/libindi/libs/webcam/port.cpp
r490 r642 38 38 #include <sys/stat.h> 39 39 #endif /* LOCKING */ 40 41 40 #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) 43 50 #include <fcntl.h> 44 51 #else 45 52 #include <sys/io.h> 46 #endif /* arm*/53 #endif /* NO_SYSIO */ 47 54 #elif defined(QNX) 48 55 #include <conio.h> … … 77 84 78 85 #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 80 87 if ((devport = open("/dev/port", O_RDWR)) < 0) { 81 88 perror("open /dev/port"); … … 87 94 return; 88 95 } 89 #endif /* arm*/96 #endif /* NO_SYSIO */ 90 97 #elif defined(FREEBSD) 91 98 if ((devio = fopen("/dev/io", "r+")) == NULL) { … … 121 128 #endif /* LOCKING */ 122 129 #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 124 131 if (devport >= 0) 125 132 close(devport); … … 129 136 // be root 130 137 perror("ioperm()"); 131 #endif /* arm*/138 #endif /* NO_SYSIO */ 132 139 #elif defined(FREEBSD) 133 140 if (devio != NULL) -
BAORadio/libindi/libindi/tools/compiler.c
r490 r642 267 267 next_token () 268 268 { 269 static c har toomv[] = "More than %d variables";270 static c har toomc[] = "More than %d constants";271 static c har 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"; 272 272 int tok = ERR; /* just something illegal */ 273 273 char c; … … 295 295 case '|': 296 296 if (*cexpr == '|') { cexpr++; tok = OR; } 297 else { (void) sprintf(err_msg, badop); return (ERR); }297 else { (void) strcpy (err_msg, badop); return (ERR); } 298 298 break; 299 299 case '&': 300 300 if (*cexpr == '&') { cexpr++; tok = AND; } 301 else { (void) sprintf(err_msg, badop); return (ERR); }301 else { (void) strcpy (err_msg, badop); return (ERR); } 302 302 break; 303 303 case '=': 304 304 if (*cexpr == '=') { cexpr++; tok = EQ; } 305 else { (void) sprintf(err_msg, badop); return (ERR); }305 else { (void) strcpy (err_msg, badop); return (ERR); } 306 306 break; 307 307 case '!': -
BAORadio/libindi/libindi/tools/evalINDI.c
r490 r642 347 347 { 348 348 char *t = tagXMLEle (root); 349 350 349 const char *d = findXMLAttValu (root, "device"); 350 const char *n = findXMLAttValu (root, "name"); 351 351 int nset = 0; 352 352 double v; … … 397 397 398 398 /* check special elements */ 399 t =findXMLAttValu (root, "state");399 t = (char *) findXMLAttValu (root, "state"); 400 400 if (t[0]) { 401 401 sprintf (prop, "%s.%s._STATE", d, n); … … 407 407 } 408 408 } 409 t =findXMLAttValu (root, "timestamp");409 t = (char *) findXMLAttValu (root, "timestamp"); 410 410 if (t[0]) { 411 411 sprintf (prop, "%s.%s._TS", d, n); -
BAORadio/libindi/libindi/tools/getINDIproperty.c
r490 r642 446 446 if (strcmp (tagXMLEle (root), defs[j].vec) == 0) { 447 447 /* legal defXXXVector, check device */ 448 char *dev =findXMLAttValu (root, "device");448 char *dev = (char *) findXMLAttValu (root, "device"); 449 449 char *idev = srchs[i].d; 450 450 if (idev[0] == WILDCARD || !strcmp (dev,idev)) { 451 451 /* found device, check name */ 452 char *nam =findXMLAttValu (root, "name");452 char *nam = (char *) findXMLAttValu (root, "name"); 453 453 char *iprop = srchs[i].p; 454 454 if (iprop[0] == WILDCARD || !strcmp (nam,iprop)) { 455 455 /* found device and name, check perm */ 456 char *perm =findXMLAttValu (root, "perm");456 char *perm = (char *) findXMLAttValu (root, "perm"); 457 457 if (!wflag && perm[0] && !strchr (perm, 'r')) { 458 458 if (verbose) … … 491 491 if (strcmp (iele, kwattr[i].keyword) == 0) { 492 492 /* 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); 494 494 sp->ok = 1; /* progress */ 495 495 if (onematch && justvalue) … … 505 505 if (!strcmp (tagXMLEle (ep), defone)) { 506 506 /* legal defXXX, check deeper */ 507 char *enam =findXMLAttValu (ep, "name");507 char *enam = (char *) findXMLAttValu (ep, "name"); 508 508 if (iele[0]==WILDCARD || !strcmp(enam,iele)) { 509 509 /* found it! */ … … 556 556 557 557 /* get format and length */ 558 format =findXMLAttValu (root, "format");558 format = (char *) findXMLAttValu (root, "format"); 559 559 isz = !strcmp (&format[strlen(format)-2], ".z"); 560 560 -
BAORadio/libindi/libindi/tools/setINDIproperty.c
r504 r642 419 419 420 420 /* 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"); 423 423 if (verbose > 1) 424 424 fprintf (stderr, "Read definition for %s.%s\n", rdev, rprop);
Note: See TracChangeset
for help on using the changeset viewer.