• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kstars

indistd.cpp

Go to the documentation of this file.
00001 /*  INDI STD
00002     Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com)
00003 
00004     This apppication is free software; you can redistribute it and/or
00005     modify it under the terms of the GNU General Public
00006     License as published by the Free Software Foundation; either
00007     version 2 of the License, or (at your option) any later version.
00008     
00009     2004-01-18: This class handles INDI Standard properties.
00010  */
00011  
00012  #include "indistd.h"
00013  #include "Options.h"
00014  #include "indielement.h"
00015  #include "indiproperty.h"
00016  #include "indigroup.h"
00017  #include "indidevice.h"
00018  #include "indidriver.h"
00019  #include "kstars.h"
00020  #include "kstarsdata.h"
00021  #include "skymap.h"
00022  #include "skyobject.h"
00023  #include "simclock.h"
00024  #include "devicemanager.h"
00025  #include "timedialog.h"
00026  #include "streamwg.h"
00027  #include "ccdpreviewwg.h"
00028  #include "fitsviewer.h"
00029  
00030  #include <sys/socket.h>
00031  #include <netinet/in.h>
00032  #include <arpa/inet.h>
00033  #include <netdb.h>
00034  #include <ctype.h>
00035  #include <zlib.h>
00036  #include <stdlib.h>
00037  
00038  #include <qtimer.h>
00039  #include <qlabel.h>
00040  #include <qfont.h>
00041  #include <qeventloop.h>
00042  #include <qsocketnotifier.h>
00043  
00044  #include <klocale.h>
00045  #include <kdebug.h>
00046  #include <kpushbutton.h>
00047  #include <klineedit.h>
00048  #include <kstatusbar.h>
00049  #include <kmessagebox.h>
00050  #include <kapplication.h>
00051  #include <kprogress.h>
00052  #include <kurl.h>
00053  #include <kdirlister.h>
00054  #include <kaction.h>
00055  
00056   
00057  #define STD_BUFFER_SIZ     1024000
00058  #define FRAME_ILEN     1024
00059  
00060  INDIStdDevice::INDIStdDevice(INDI_D *associatedDevice, KStars * kswPtr)
00061  {
00062  
00063    dp           = associatedDevice;
00064    ksw          = kswPtr;
00065    initDevCounter   = 0;
00066    seqCount     = 0;
00067    batchMode        = false;
00068    ISOMode          = false;
00069    
00070    currentObject    = NULL; 
00071    streamWindow     = new StreamWG(this, ksw);
00072    CCDPreviewWindow     = new CCDPreviewWG(this, ksw);
00073      
00074    devTimer         = new QTimer(this);
00075    seqLister        = new KDirLister();
00076    
00077    telescopeSkyObject   = new SkyObject(0, 0, 0, 0, i18n("Telescope"));
00078    ksw->data()->appendTelescopeObject(telescopeSkyObject);
00079     
00080    connect( devTimer, SIGNAL(timeout()), this, SLOT(timerDone()) );
00081    connect( seqLister, SIGNAL(newItems (const KFileItemList & )), this, SLOT(checkSeqBoundary(const KFileItemList &)));
00082    
00083    downloadDialog = new KProgressDialog(NULL, 0, i18n("INDI"), i18n("Downloading Data..."));
00084    downloadDialog->cancel();
00085    
00086    parser       = newLilXML();
00087  }
00088  
00089  INDIStdDevice::~INDIStdDevice()
00090  {
00091    streamWindow->enableStream(false);
00092    streamWindow->close();
00093    CCDPreviewWindow->enableStream(false);
00094    CCDPreviewWindow->close();
00095    streamDisabled();
00096    delete (seqLister);
00097  }
00098  
00099 void INDIStdDevice::handleBLOB(unsigned char *buffer, int bufferSize, QString dataFormat)
00100 {
00101 
00102   if (dataFormat == ".fits") dataType = DATA_FITS;
00103   else if (dataFormat == ".stream") dataType = DATA_STREAM;
00104   else if (dataFormat == ".ccdpreview") dataType = DATA_CCDPREVIEW;   
00105   else dataType = DATA_OTHER;
00106 
00107   if (dataType == DATA_STREAM)
00108   {
00109     if (!streamWindow->processStream)
00110       return;
00111     
00112     streamWindow->show();   
00113     streamWindow->streamFrame->newFrame( buffer, bufferSize, streamWindow->streamWidth, streamWindow->streamHeight);    
00114   }
00115   else if (dataType == DATA_CCDPREVIEW)
00116   {
00117     if (!CCDPreviewWindow->processStream)
00118       return;
00119     CCDPreviewWindow->show();   
00120     CCDPreviewWindow->streamFrame->newFrame( buffer, bufferSize, CCDPreviewWindow->streamWidth, CCDPreviewWindow->streamHeight);    
00121   }
00122   else if (dataType == DATA_FITS || dataType == DATA_OTHER)
00123   {
00124     char filename[256];
00125     FILE *fitsTempFile;
00126     int fd, nr, n=0;
00127     QString currentDir = Options::fitsSaveDirectory();
00128        
00129     streamWindow->close();
00130         
00131     if (dataType == DATA_FITS && !batchMode && Options::indiFITSDisplay())
00132     {
00133       strcpy(filename, "/tmp/fitsXXXXXX");
00134       if ((fd = mkstemp(filename)) < 0)
00135       { 
00136     KMessageBox::error(NULL, "Error making temporary filename.");
00137     return;
00138       }
00139       close(fd);
00140     }
00141     else
00142     {
00143       char ts[32];
00144       struct tm *tp;
00145       time_t t;
00146       time (&t);
00147       tp = gmtime (&t);
00148       
00149       if (currentDir[currentDir.length() -1] == '/')
00150     currentDir.truncate(currentDir.length() - 1);
00151       
00152       strncpy(filename, currentDir.ascii(), currentDir.length());
00153       filename[currentDir.length()] = '\0';
00154       
00155       if (dataType == DATA_FITS)
00156       {
00157     char tempFileStr[256];
00158     strncpy(tempFileStr, filename, 256);
00159         
00160     if ( batchMode && !ISOMode)
00161       snprintf(filename, sizeof(filename), "%s/%s_%02d.fits", tempFileStr, seqPrefix.ascii(), seqCount);
00162     else if (!batchMode && !Options::indiFITSDisplay())
00163     {
00164       strftime (ts, sizeof(ts), "%Y-%m-%dT%H:%M:%S", tp);
00165       snprintf(filename, sizeof(filename), "%s/file_%s.fits", tempFileStr, ts);
00166     }
00167     else
00168     {
00169       strftime (ts, sizeof(ts), "%Y-%m-%dT%H:%M:%S", tp);
00170       snprintf(filename, sizeof(filename), "%s/%s_%02d_%s.fits", tempFileStr, seqPrefix.ascii(), seqCount, ts);
00171     }
00172          
00173     seqCount++;
00174       }
00175       else
00176       {
00177     strftime (ts, sizeof(ts), "/file-%Y-%m-%dT%H:%M:%S.", tp);
00178     strncat(filename, ts, sizeof(ts));
00179     strncat(filename, dataFormat.ascii(), 10);
00180       }
00181     }
00182       
00183     fitsTempFile = fopen(filename, "w");
00184        
00185     if (fitsTempFile == NULL) return;
00186        
00187     for (nr=0; nr < (int) bufferSize; nr += n)
00188       n = fwrite( ((unsigned char *) buffer) + nr, 1, bufferSize - nr, fitsTempFile);
00189        
00190     fclose(fitsTempFile);
00191        
00192        // We're done if we have DATA_OTHER
00193     if (dataType == DATA_OTHER)
00194     {
00195       ksw->statusBar()->changeItem( i18n("Data file saved to %1").arg(filename), 0);
00196       return;
00197     }
00198     else if (dataType == DATA_FITS && (batchMode || !Options::indiFITSDisplay()))
00199     {
00200       ksw->statusBar()->changeItem( i18n("FITS file saved to %1").arg(filename), 0);
00201       emit FITSReceived(dp->label);
00202       return;
00203     } 
00204        
00205     KURL fileURL(filename);
00206        
00207     FITSViewer * fv = new FITSViewer(&fileURL, ksw);
00208     fv->fitsChange();
00209     fv->show();
00210   }
00211        
00212 }
00213 
00214  /* Process standard Text and Number properties arrives from the driver */
00215  void INDIStdDevice::setTextValue(INDI_P *pp)
00216  {
00217    INDI_E *el;
00218    int wd, ht, bpp, bo, mu;
00219    long mgd;
00220    double fwhm;
00221    int d, m, y, min, sec, hour;
00222    ExtDate indiDate;
00223    QTime indiTime;
00224    KStarsDateTime indiDateTime;
00225    
00226   switch (pp->stdID)
00227   {
00228 
00229     case TIME:
00230       if ( Options::indiAutoTime() )
00231        handleDevCounter();
00232        
00233        // Update KStars time once we receive update from INDI
00234        el = pp->findElement("UTC");
00235        if (!el) return;
00236        
00237        sscanf(el->text.ascii(), "%d%*[^0-9]%d%*[^0-9]%dT%d%*[^0-9]%d%*[^0-9]%d", &y, &m, &d, &hour, &min, &sec);
00238        indiDate.setYMD(y, m, d);
00239        indiTime.setHMS(hour, min, sec);
00240        indiDateTime.setDate(indiDate);
00241        indiDateTime.setTime(indiTime);
00242        
00243        ksw->data()->changeDateTime(indiDateTime);
00244        ksw->data()->syncLST();
00245        
00246       break;
00247       
00248     case SDTIME:
00249       if ( Options::indiAutoTime())
00250        handleDevCounter();
00251       break;
00252     
00253     case GEOGRAPHIC_COORD:
00254       if ( Options::indiAutoGeo() )
00255        handleDevCounter();
00256       break;
00257       
00258     case CCD_EXPOSE_DURATION:
00259        if (pp->state == PS_IDLE || pp->state == PS_OK)
00260          pp->set_w->setText(i18n("Start"));
00261        break;
00262        
00263     case CCD_FRAME:
00264          el = pp->findElement("WIDTH");
00265      if (!el) return;
00266      wd = (int) el->value;
00267      el = pp->findElement("HEIGHT");
00268      if (!el) return;
00269      ht = (int) el->value;
00270      
00271      streamWindow->setSize(wd, ht);
00272      //streamWindow->allocateStreamBuffer();
00273      break;
00274     case CCDPREVIEW_CTRL:    
00275          el = pp->findElement("WIDTH");
00276      if (!el) return;
00277      wd = (int) el->value;
00278      el = pp->findElement("HEIGHT");
00279      if (!el) return;
00280      ht = (int) el->value;
00281      el = pp->findElement("BYTEORDER");
00282      if (!el) return;
00283      bo = (int) el->value;
00284      el = pp->findElement("BYTESPERPIXEL");
00285      if (!el) return;
00286      bpp = (int) el->value;  
00287      el = pp->findElement("MAXGOODDATA");
00288      if (!el) return;
00289      mgd = (long) el->value;
00290      CCDPreviewWindow->setCtrl(wd, ht, bo ,bpp,mgd);
00291          
00292      break;
00293 
00294    case CCD_INFO:
00295      el = pp->findElement("CCD_FWHM_PIXEL");
00296      if (!el) return;
00297      fwhm = el->value;
00298      el = pp->findElement("CCD_PIXEL_SIZE");
00299      if (!el) return;
00300      mu = (int) el->value;
00301      CCDPreviewWindow->setCCDInfo(fwhm, mu);
00302      break;
00303 
00304        case EQUATORIAL_COORD:
00305        case EQUATORIAL_EOD_COORD:
00306     if (!dp->isOn()) break;
00307     el = pp->findElement("RA");
00308     if (!el) return;
00309     telescopeSkyObject->setRA(el->value);
00310     el = pp->findElement("DEC");
00311     if (!el) return;
00312     telescopeSkyObject->setDec(el->value);
00313     telescopeSkyObject->EquatorialToHorizontal(ksw->LST(), ksw->geo()->lat());
00314     // Force immediate update of skymap if the focus object is our telescope. 
00315     if (ksw->map()->focusObject() == telescopeSkyObject)
00316         ksw->map()->updateFocus();
00317     else  
00318         ksw->map()->update();
00319     break;
00320 
00321     case HORIZONTAL_COORD:
00322         if (!dp->isOn()) break;
00323     el = pp->findElement("ALT");
00324     if (!el) return;
00325     telescopeSkyObject->setAlt(el->value);
00326     el = pp->findElement("AZ");
00327     if (!el) return;
00328     telescopeSkyObject->setAz(el->value);
00329     telescopeSkyObject->HorizontalToEquatorial(ksw->LST(), ksw->geo()->lat());
00330     // Force immediate update of skymap if the focus object is our telescope. 
00331     if (ksw->map()->focusObject() == telescopeSkyObject)
00332           ksw->map()->updateFocus();
00333     else
00334           ksw->map()->update();
00335     break;
00336 
00337     default:
00338         break;
00339     
00340   }
00341  
00342  }
00343 
00344  void INDIStdDevice::setLabelState(INDI_P *pp)
00345  {
00346     INDI_E *lp;
00347     INDI_P *imgProp;
00348     KAction *tmpAction;
00349     INDIDriver *drivers = ksw->getINDIDriver();
00350     QFont buttonFont;
00351     
00352     switch (pp->stdID)
00353     {
00354       case CONNECTION:
00355       lp = pp->findElement("CONNECT");
00356       if (!lp) return;
00357       
00358       if (lp->state == PS_ON)
00359       {
00360         initDeviceOptions();
00361     emit linkAccepted();
00362 
00363         imgProp = dp->findProp("CCD_EXPOSE_DURATION");
00364     if (imgProp)
00365     {
00366             tmpAction = ksw->actionCollection()->action("capture_sequence");
00367         if (!tmpAction)
00368             kdDebug() << "Warning: capture_sequence action not found" << endl;
00369         else
00370             tmpAction->setEnabled(true);
00371         }
00372       }
00373       else
00374       {
00375         if (streamWindow)
00376     {
00377       //sNotifier->disconnect();
00378       //dp->parentMgr->sNotifier->disconnect();
00379       streamWindow->enableStream(false);
00380       streamWindow->close();
00381       
00382         //close(streamFD);
00383     }
00384     
00385     if (ksw->map()->focusObject() == telescopeSkyObject)
00386     {
00387         ksw->map()->stopTracking();
00388         ksw->map()->setFocusObject(NULL);
00389     }
00390 
00391     drivers->updateMenuActions();
00392         ksw->map()->forceUpdateNow();
00393         emit linkRejected();
00394       }
00395       break;
00396       
00397       case VIDEO_STREAM:
00398        lp = pp->findElement("ON");
00399        if (!lp) return;
00400        if (lp->state == PS_ON)
00401           streamWindow->enableStream(true);
00402        else
00403           streamWindow->enableStream(false);
00404        break;
00405        
00406        case CCDPREVIEW_STREAM:
00407        lp = pp->findElement("ON");
00408        if (!lp) return;
00409        if (lp->state == PS_ON)
00410           CCDPreviewWindow->enableStream(true);
00411        else
00412           CCDPreviewWindow->enableStream(false);
00413        break;
00414        
00415     default:
00416       break;
00417     }
00418  
00419  }
00420 
00421  void INDIStdDevice::streamDisabled()
00422  {
00423     INDI_P *pp;
00424     INDI_E *el;
00425     
00426     //pp = dp->findProp("CONNECTION");
00427     //if (!pp) return;
00428     //if (pp->state == PS_OFF) return;
00429     
00430     pp = dp->findProp("VIDEO_STREAM");
00431     if (!pp) return;
00432     
00433     el = pp->findElement("OFF");
00434     if (!el) return;
00435     
00436     if (el->state == PS_ON)
00437      return;
00438     
00439     // Turn stream off
00440     pp->newSwitch(1); 
00441    
00442 }
00443  
00444  void INDIStdDevice::updateSequencePrefix(QString newPrefix)
00445  {
00446     seqPrefix = newPrefix;
00447     
00448     seqLister->setNameFilter(QString("%1_*.fits").arg(seqPrefix));
00449     
00450     seqCount = 0;
00451     
00452     if (ISOMode) return;
00453     
00454     seqLister->openURL(Options::fitsSaveDirectory());
00455     
00456     checkSeqBoundary(seqLister->items());
00457  
00458  }
00459  
00460  void INDIStdDevice::checkSeqBoundary(const KFileItemList & items)
00461  {
00462     int newFileIndex;
00463     QString tempName;
00464     char *tempPrefix = new char[64];
00465     
00466     // No need to check when in ISO mode
00467     if (ISOMode)
00468      return;
00469      
00470     for ( KFileItemListIterator it( items ) ; it.current() ; ++it )
00471     {
00472        tempName = it.current()->name();
00473        
00474        // find the prefix first
00475        if (tempName.find(seqPrefix) == -1)
00476          continue;
00477      
00478        strncpy(tempPrefix, tempName.ascii(), 64);
00479        tempPrefix[63] = '\0';
00480        
00481        char * t = tempPrefix;
00482        
00483        // skip chars
00484        while (*t) { if (isdigit(*t)) break; t++; }
00485        //tempPrefix = t;
00486        
00487        newFileIndex = strtol(t, NULL, 10);
00488        
00489         if (newFileIndex >= seqCount)
00490       seqCount = newFileIndex + 1;
00491    }
00492    
00493    delete [] (tempPrefix);
00494           
00495  }
00496  
00497  void INDIStdDevice::updateTime()
00498 {
00499   INDI_P *pp;
00500   INDI_E *lp;
00501   
00502   pp = dp->findProp("TIME");
00503   if (!pp) return;
00504   
00505   lp = pp->findElement("UTC");
00506   
00507   if (!lp) return;
00508   
00509   QTime newTime( ksw->data()->ut().time());
00510   ExtDate newDate( ksw->data()->ut().date());
00511 
00512   lp->write_w->setText(QString("%1-%2-%3T%4:%5:%6").arg(newDate.year()).arg(newDate.month())
00513                     .arg(newDate.day()).arg(newTime.hour())
00514                     .arg(newTime.minute()).arg(newTime.second()));
00515   pp->newText();
00516   
00517   pp  = dp->findProp("SDTIME");
00518   if (!pp) return;
00519   lp = pp->findElement("LST");
00520   if (!lp) return;
00521    
00522   lp->write_w->setText(ksw->LST()->toHMSString());
00523   pp->newText();
00524 }
00525 
00526 void INDIStdDevice::updateLocation()
00527 {
00528    INDI_P *pp;
00529    INDI_E * latEle, * longEle;
00530    GeoLocation *geo = ksw->geo();
00531 
00532    pp = dp->findProp("GEOGRAPHIC_COORD");
00533    if (!pp) return;
00534     
00535   dms tempLong (geo->lng()->degree(), geo->lng()->arcmin(), geo->lng()->arcsec());
00536   dms fullCir(360,0,0);
00537 
00538   if (tempLong.degree() < 0)
00539      tempLong.setD ( fullCir.Degrees() + tempLong.Degrees());
00540 
00541     latEle  = pp->findElement("LAT");
00542     if (!latEle) return;
00543     longEle = pp->findElement("LONG");
00544     if (!longEle) return;
00545     
00546     longEle->write_w->setText(QString("%1:%2:%3").arg(tempLong.degree()).arg(tempLong.arcmin()).arg(tempLong.arcsec()));
00547     latEle->write_w->setText(QString("%1:%2:%3").arg(geo->lat()->degree()).arg(geo->lat()->arcmin()).arg(geo->lat()->arcsec()));
00548     
00549     pp->newText();
00550 }
00551 
00552  
00553  void INDIStdDevice::registerProperty(INDI_P *pp)
00554  {
00555    INDI_E * portEle;
00556    INDIDriver *drivers = ksw->getINDIDriver();
00557    QString str;
00558  
00559    switch (pp->stdID)
00560    {
00561      case DEVICE_PORT:
00562      portEle = pp->findElement("PORT");
00563      if (!portEle) return;
00564      
00565      if (drivers)
00566      {
00567        for (unsigned int i=0; i < drivers->devices.size(); i++)
00568        {
00569          if (drivers->devices[i]->mgrID == dp->parentMgr->mgrID)
00570      {
00571             if (drivers->devices[i]->deviceType == KSTARS_TELESCOPE)
00572         {
00573                portEle->read_w->setText( Options::indiTelescopePort() );
00574                portEle->write_w->setText( Options::indiTelescopePort() );
00575                portEle->text = Options::indiTelescopePort();
00576            break;
00577         }
00578         else if (drivers->devices[i]->deviceType == KSTARS_VIDEO)
00579         {
00580            portEle->read_w->setText( Options::indiVideoPort() );
00581                portEle->write_w->setText( Options::indiVideoPort() );
00582                portEle->text = Options::indiVideoPort();
00583            break;
00584         }
00585     }
00586       }     
00587      }
00588      break;
00589      
00590    }
00591   
00592 }
00593  
00594 void INDIStdDevice::initDeviceOptions()
00595 {
00596 
00597   INDI_P *prop;
00598 
00599   initDevCounter = 0;
00600 
00601   if ( Options::indiAutoTime() )
00602   {
00603     prop = dp->findProp("TIME");
00604       if (prop)
00605       {
00606             updateTime();
00607         initDevCounter += 5;
00608       }
00609   }
00610 
00611   if ( Options::indiAutoGeo() )
00612   {
00613     prop = dp->findProp("GEOGRAPHIC_COORD");
00614     if (prop)
00615     {
00616         updateLocation();
00617             initDevCounter += 2;
00618     }
00619   }
00620 
00621   if ( Options::indiMessages() )
00622     ksw->statusBar()->changeItem( i18n("%1 is online.").arg(dp->name), 0);
00623 
00624   ksw->map()->forceUpdateNow();
00625 }
00626 
00627  void INDIStdDevice::handleDevCounter()
00628 {
00629 
00630   if (initDevCounter <= 0)
00631    return;
00632 
00633   initDevCounter--;
00634 
00635   if ( initDevCounter == 0 && Options::indiMessages() )
00636     ksw->statusBar()->changeItem( i18n("%1 is online and ready.").arg(dp->name), 0);
00637 
00638 }
00639 
00640 bool INDIStdDevice::handleNonSidereal()
00641 {
00642    if (!currentObject)
00643       return false;
00644 
00645     int trackIndex=0;
00646     INDI_E *nameEle;
00647 
00648     kdDebug() << "Object of type " << currentObject->typeName() << endl;
00649   //TODO Meade claims that the library access is available to
00650   // all telescopes, which is unture. Only classic meade support
00651   // that. They claim that library funcion will be available to all
00652   // in "later" firmware revisions for the autostar and GPS.
00653   // As a temprory solution, I'm going to explicity check for the
00654   // device name which ideally I'm not supposed to do since all properties
00655   // should be defined from the INDI driver, but since the INDI autostar
00656   // and gps define the library functions (based on Meade's future claims)
00657   // I will check the device name until Meade's respondes to my query.
00658 
00659   // Update: Solution
00660   // Only Meade Classic will offer an explicit SOLAR_SYSTEM property. If such a property exists
00661   // then we take advantage of it. Otherwise, we send RA/DEC to the telescope and start a timer
00662   // based on the object type. Objects with high proper motions will require faster updates.
00663   // handle Non Sideral is ONLY called when tracking an object, not slewing.
00664   INDI_P *prop = dp->findProp(QString("SOLAR_SYSTEM"));
00665   INDI_P *setMode = dp->findProp(QString("ON_COORD_SET"));
00666 
00667   // If the device support it
00668   if (prop && setMode)
00669   {
00670     for (unsigned int i=0; i < setMode->el.count(); i++)
00671       if (setMode->el.at(i)->name == "TRACK")
00672       { trackIndex = i; break; }
00673 
00674     kdDebug() << "Device supports SOLAR_SYSTEM property" << endl;
00675 
00676     for (unsigned int i=0; i < prop->el.count(); i++)
00677      if (currentObject->name().lower() == prop->el.at(i)->label.lower())
00678      {
00679        prop->newSwitch(i);
00680        setMode->newSwitch(trackIndex);
00681        
00682        /* Send object name if available */
00683        nameEle = dp->findElem("OBJECT_NAME");
00684        if (nameEle && nameEle->pp->perm != PP_RO)
00685        {
00686            nameEle->write_w->setText(currentObject->name());
00687            nameEle->pp->newText();
00688        }
00689 
00690        return true;
00691      }
00692   }
00693 
00694    kdDebug() << "Device doesn't support SOLAR_SYSTEM property, issuing a timer" << endl;
00695    kdDebug() << "Starting timer for object of type " << currentObject->typeName() << endl;
00696    
00697 
00698    switch (currentObject->type())
00699    {
00700     // Planet/Moon
00701     case 2:
00702        kdDebug() << "Initiating pulse tracking for " << currentObject->name() << endl;
00703        devTimer->start(INDI_PULSE_TRACKING);
00704        break;
00705     // Comet/Asteroid
00706     case 9:
00707     case 10:
00708       kdDebug() << "Initiating pulse tracking for " << currentObject->name() << endl;
00709       devTimer->start(INDI_PULSE_TRACKING);
00710       break;
00711     default:
00712       break;
00713     }
00714 
00715    return false;
00716 }
00717 
00718 
00719 void INDIStdDevice::timerDone()
00720 {
00721       INDI_P *prop;
00722       INDI_E *RAEle, *DecEle;
00723       INDI_E *el;
00724       bool useJ2000 = false;
00725 
00726        if (!dp->isOn())
00727        {
00728         devTimer->stop();
00729     return;
00730        }
00731 
00732        prop = dp->findProp("ON_COORD_SET");
00733        if (prop == NULL || !currentObject)
00734         return;
00735 
00736        el   = prop->findElement("TRACK");
00737        if (!el) return;
00738        
00739        if (el->state != PS_ON)
00740        {
00741         devTimer->stop();
00742         return;
00743        }
00744     
00745        prop = dp->findProp("EQUATORIAL_EOD_COORD");
00746        
00747        if (prop == NULL)
00748        {
00749          prop = dp->findProp("EQUATORIAL_COORD");
00750      if (prop) useJ2000 = true;
00751        }
00752        
00753        if (prop == NULL || !currentObject)
00754         return;
00755 
00756        // wait until slew is done
00757        if (prop->state == PS_BUSY)
00758         return;
00759 
00760        kdDebug() << "Timer called, starting processing" << endl;
00761 
00762     SkyPoint sp(currentObject->ra(), currentObject->dec());
00763     
00764     kdDebug() << "RA: " << currentObject->ra()->toHMSString() << " - DEC: " << currentObject->dec()->toDMSString() << endl;
00765     kdDebug() << "Az: " << currentObject->az()->toHMSString() << " - Alt " << currentObject->alt()->toDMSString() << endl;
00766 
00767     if (useJ2000)
00768     {
00769         sp.set(currentObject->ra(), currentObject->dec());
00770             sp.apparentCoord( ksw->data()->ut().djd() , (long double) J2000);
00771         }
00772 
00773        // We need to get from JNow (Skypoint) to J2000
00774        // The ra0() of a skyPoint is the same as its JNow ra() without this process
00775 
00776        // Use J2000 coordinate as required by INDI
00777        RAEle  = prop->findElement("RA");
00778        if (!RAEle) return;
00779        DecEle = prop->findElement("DEC");
00780        if (!DecEle) return;
00781      
00782        RAEle->write_w->setText(QString("%1:%2:%3").arg(sp.ra()->hour())
00783                                  .arg(sp.ra()->minute())
00784                              .arg(sp.ra()->second()));
00785         DecEle->write_w->setText(QString("%1:%2:%3").arg(sp.dec()->degree())
00786                                                          .arg(sp.dec()->arcmin())
00787                              .arg(sp.dec()->arcsec()));
00788     prop->newText();
00789 
00790 }
00791 
00792 INDIStdProperty::INDIStdProperty(INDI_P *associatedProperty, KStars * kswPtr, INDIStdDevice *stdDevPtr)
00793 {
00794    pp     = associatedProperty;
00795    ksw    = kswPtr;
00796    stdDev = stdDevPtr;
00797 }
00798  
00799  INDIStdProperty::~INDIStdProperty() 
00800  {
00801  
00802  }
00803  
00804  void INDIStdProperty::newText()
00805  {
00806    INDI_E *lp;
00807    INDIDriver *drivers = ksw->getINDIDriver();
00808    
00809    switch (pp->stdID)
00810    {
00811      /* Set expose duration button to 'cancel' when busy */
00812      case CCD_EXPOSE_DURATION:
00813        pp->set_w->setText(i18n("Cancel"));
00814        break;
00815      
00816       /* Save Port name in KStars options */
00817      case DEVICE_PORT:
00818         lp = pp->findElement("PORT");
00819     
00820         if (lp && drivers) 
00821     {
00822           for (unsigned int i=0; i < drivers->devices.size(); i++)
00823           {
00824               if (drivers->devices[i]->mgrID == stdDev->dp->parentMgr->mgrID)
00825           {
00826             if (drivers->devices[i]->deviceType == KSTARS_TELESCOPE)
00827         {
00828            Options::setIndiTelescopePort( lp->text );
00829            kdDebug() << "Setting telescope port " << lp->text << endl;
00830         }
00831         else if (drivers->devices[i]->deviceType == KSTARS_VIDEO)
00832         {
00833            Options::setIndiVideoPort( lp->text );
00834            kdDebug() << "Setting video port " << lp->text << endl;
00835         }
00836         break;
00837           }
00838       }
00839         }
00840      
00841     break;
00842    }
00843  
00844  }
00845  
00846  bool INDIStdProperty::convertSwitch(int switchIndex, INDI_E *lp)
00847  {
00848  
00849   INDI_E *RAEle(NULL), *DecEle(NULL), *AzEle(NULL), *AltEle(NULL), *nameEle(NULL);
00850   INDI_P * prop;
00851   SkyPoint sp;
00852   int selectedCoord=0;              /* 0 for Equatorial, 1 for Horizontal */
00853   bool useJ2000 (false);
00854   
00855   switch (pp->stdID)
00856   {
00857     /* Handle Slew/Track/Sync */
00858     case ON_COORD_SET:
00859         // #1 set current object to NULL
00860         stdDev->currentObject = NULL;
00861     // #2 Deactivate timer if present
00862     if (stdDev->devTimer->isActive())
00863             stdDev->devTimer->stop();
00864 
00865     prop = pp->pg->dp->findProp("EQUATORIAL_EOD_COORD");
00866         if (prop == NULL)
00867     {
00868           prop = pp->pg->dp->findProp("EQUATORIAL_COORD");
00869           if (prop == NULL)
00870                   {
00871                     prop = pp->pg->dp->findProp("HORIZONTAL_COORD");
00872                     if (prop == NULL)
00873                 return false;
00874                     else
00875                         selectedCoord = 1;      /* Select horizontal */
00876                   }
00877           else
00878                 useJ2000 = true;
00879     }
00880 
00881         switch (selectedCoord)
00882         {
00883           // Equatorial
00884           case 0:
00885            if (prop->perm == PP_RO) return false;
00886            RAEle  = prop->findElement("RA");
00887            if (!RAEle) return false;
00888        DecEle = prop->findElement("DEC");
00889        if (!DecEle) return false;
00890            break;
00891 
00892          // Horizontal
00893          case 1:
00894           if (prop->perm == PP_RO) return false;
00895           AzEle = prop->findElement("AZ");
00896           if (!AzEle) return false;
00897           AltEle = prop->findElement("ALT");
00898           if (!AltEle) return false;
00899           break;
00900         }
00901    
00902         stdDev->currentObject = ksw->map()->clickedObject();
00903     // Track is similar to slew, except that for non-sidereal objects
00904     // it tracks the objects automatically via a timer.
00905     if ((lp->name == "TRACK"))
00906             if (stdDev->handleNonSidereal())
00907                 return true;
00908 
00909       /* Send object name if available */
00910       if (stdDev->currentObject)
00911           {
00912              nameEle = pp->pg->dp->findElem("OBJECT_NAME");
00913              if (nameEle && nameEle->pp->perm != PP_RO)
00914              {
00915                  nameEle->write_w->setText(stdDev->currentObject->name());
00916                  nameEle->pp->newText();
00917              }
00918           }
00919 
00920        switch (selectedCoord)
00921        {
00922          case 0:
00923             if (stdDev->currentObject)
00924         sp.set (stdDev->currentObject->ra(), stdDev->currentObject->dec());
00925             else
00926                 sp.set (ksw->map()->clickedPoint()->ra(), ksw->map()->clickedPoint()->dec());
00927 
00928          if (useJ2000)
00929             sp.apparentCoord(ksw->data()->ut().djd(), (long double) J2000);
00930 
00931            RAEle->write_w->setText(QString("%1:%2:%3").arg(sp.ra()->hour()).arg(sp.ra()->minute()).arg(sp.ra()->second()));
00932        DecEle->write_w->setText(QString("%1:%2:%3").arg(sp.dec()->degree()).arg(sp.dec()->arcmin()).arg(sp.dec()->arcsec()));
00933 
00934           break;
00935 
00936        case 1:
00937          if (stdDev->currentObject)
00938          {
00939            sp.setAz(*stdDev->currentObject->az());
00940            sp.setAlt(*stdDev->currentObject->alt());
00941          }
00942          else
00943          {
00944            sp.setAz(*ksw->map()->clickedPoint()->az());
00945            sp.setAlt(*ksw->map()->clickedPoint()->alt());
00946          }
00947 
00948           AzEle->write_w->setText(QString("%1:%2:%3").arg(sp.az()->degree()).arg(sp.az()->arcmin()).arg(sp.az()->arcsec()));
00949           AltEle->write_w->setText(QString("%1:%2:%3").arg(sp.alt()->degree()).arg(sp.alt()->arcmin()).arg(sp.alt()->arcsec()));
00950 
00951          break;
00952        }
00953 
00954        pp->newSwitch(switchIndex);
00955        prop->newText();
00956     
00957     return true;
00958     break;
00959    
00960    /* Handle Abort */
00961    case ABORT_MOTION:
00962          kdDebug() << "Stopping timer." << endl;
00963      stdDev->devTimer->stop();
00964      pp->newSwitch(switchIndex);
00965      return true;
00966      break;
00967      
00968    case MOVEMENT:
00969       pp->newSwitch(switchIndex);
00970       break;
00971       
00972    default:
00973          return false;
00974      break;
00975    }
00976   
00977   return false;
00978  
00979  }
00980  
00981 // Return true if the complete operation is done here, or false if the operation is to be completed in the properties newSwitch()
00982 bool INDIStdProperty::newSwitch(int id, INDI_E* el)
00983 {
00984   INDI_P *prop;
00985   el=el; 
00986 
00987   switch (pp->stdID)
00988   {
00989     case CONNECTION: 
00990       if (id == 1)
00991         stdDev->streamDisabled();
00992       else
00993       { 
00994        prop = pp->pg->dp->findProp("DEVICE_PORT");
00995        if (prop)
00996        prop->newText();
00997       }
00998       break;
00999     case ABORT_MOTION:
01000     case PARK:
01001     case MOVEMENT:
01002        //TODO add text in the status bar "Slew aborted."
01003        stdDev->devTimer->stop();
01004        break;
01005     default:
01006        break;
01007    }
01008    
01009    return false;
01010 
01011 }
01012 
01013 void INDIStdProperty::newTime()
01014 {
01015    INDI_E * timeEle;
01016    INDI_P *SDProp;
01017    
01018    timeEle = pp->findElement("UTC");
01019    if (!timeEle) return;
01020    
01021    TimeDialog timedialog ( ksw->data()->ut(), ksw );
01022 
01023     if ( timedialog.exec() == QDialog::Accepted )
01024     {
01025         QTime newTime( timedialog.selectedTime() );
01026         ExtDate newDate( timedialog.selectedDate() );
01027 
01028                 timeEle->write_w->setText(QString("%1-%2-%3T%4:%5:%6")
01029                     .arg(newDate.year()).arg(newDate.month())
01030                     .arg(newDate.day()).arg(newTime.hour())
01031                     .arg(newTime.minute()).arg(newTime.second()));
01032             pp->newText();
01033     }
01034     else return;
01035     
01036    SDProp  = pp->pg->dp->findProp("SDTIME");
01037    if (!SDProp) return;
01038    timeEle = SDProp->findElement("LST");
01039    if (!timeEle) return;
01040    
01041    timeEle->write_w->setText(ksw->LST()->toHMSString());
01042    SDProp->newText();
01043 }
01044 
01045 #include "indistd.moc"

kstars

Skip menu "kstars"
  • Main Page
  • Modules
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • keduca
  • kstars
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal