summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJasem Mutlaq <mutlaqja@ikarustech.com>2016-09-24 20:19:53 (GMT)
committerJasem Mutlaq <mutlaqja@ikarustech.com>2016-09-24 20:19:53 (GMT)
commite901f7d04d188540b5bafe1bbe9d4f2a9aacfed1 (patch)
tree3adeeb07ecc1357cd578286805d5526100aaccd7
parent9ee9a4ced09721754974ff1dc7ca4c015bce0518 (diff)
Add new guide interface files. Organizing Ekos hierarchy
-rw-r--r--kstars/ekos/QProgressIndicator.cpp137
-rw-r--r--kstars/ekos/QProgressIndicator.h108
-rw-r--r--kstars/ekos/align.cpp1909
-rw-r--r--kstars/ekos/align.h460
-rw-r--r--kstars/ekos/align.ui973
-rw-r--r--kstars/ekos/astrometryparser.h48
-rw-r--r--kstars/ekos/calibrationoptions.ui277
-rw-r--r--kstars/ekos/capture.cpp3805
-rw-r--r--kstars/ekos/capture.h590
-rw-r--r--kstars/ekos/capture.ui1602
-rw-r--r--kstars/ekos/darklibrary.cpp282
-rw-r--r--kstars/ekos/darklibrary.h76
-rw-r--r--kstars/ekos/dome.cpp118
-rw-r--r--kstars/ekos/dome.h92
-rw-r--r--kstars/ekos/dustcap.cpp124
-rw-r--r--kstars/ekos/dustcap.h105
-rw-r--r--kstars/ekos/focus.cpp2332
-rw-r--r--kstars/ekos/focus.h483
-rw-r--r--kstars/ekos/focus.ui938
-rw-r--r--kstars/ekos/guide.h348
-rw-r--r--kstars/ekos/guide.ui182
-rw-r--r--kstars/ekos/guide/guideinterface.cpp (renamed from kstars/ekos/guide.cpp)6
-rw-r--r--kstars/ekos/guide/guideinterface.h37
-rw-r--r--kstars/ekos/guide/internalguide/internalguider.cpp (renamed from kstars/ekos/astrometryparser.cpp)19
-rw-r--r--kstars/ekos/guide/internalguide/internalguider.h26
-rw-r--r--kstars/ekos/mosaic.cpp571
-rw-r--r--kstars/ekos/mosaic.h148
-rw-r--r--kstars/ekos/mosaic.ui746
-rw-r--r--kstars/ekos/mount.cpp685
-rw-r--r--kstars/ekos/mount.h233
-rw-r--r--kstars/ekos/mount.ui556
-rw-r--r--kstars/ekos/offlineastrometryparser.cpp296
-rw-r--r--kstars/ekos/offlineastrometryparser.h65
-rw-r--r--kstars/ekos/onlineastrometryparser.cpp524
-rw-r--r--kstars/ekos/onlineastrometryparser.h83
-rw-r--r--kstars/ekos/phd2.cpp591
-rw-r--r--kstars/ekos/phd2.h104
-rw-r--r--kstars/ekos/remoteastrometryparser.cpp167
-rw-r--r--kstars/ekos/remoteastrometryparser.h60
-rw-r--r--kstars/ekos/scheduler.cpp4665
-rw-r--r--kstars/ekos/scheduler.h561
-rw-r--r--kstars/ekos/scheduler.ui1467
-rw-r--r--kstars/ekos/schedulerjob.cpp427
-rw-r--r--kstars/ekos/schedulerjob.h162
-rw-r--r--kstars/ekos/sequencejob.cpp422
-rw-r--r--kstars/ekos/sequencejob.h206
-rw-r--r--kstars/ekos/weather.cpp58
-rw-r--r--kstars/ekos/weather.h72
48 files changed, 71 insertions, 27875 deletions
diff --git a/kstars/ekos/QProgressIndicator.cpp b/kstars/ekos/QProgressIndicator.cpp
deleted file mode 100644
index 425dc57..0000000
--- a/kstars/ekos/QProgressIndicator.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
-*
-* This file is part of QProgressIndicator,
-* an open-source recent files menu widget
-*
-* Copyright (C) 2009 - 2010 Morgan Leborgne
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Lesser General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public License
-* along with QRecentFilesMenu. If not, see <http://www.gnu.org/licenses/>.
-*
-*/
-#include "QProgressIndicator.h"
-
-#include <QPainter>
-
-QProgressIndicator::QProgressIndicator(QWidget* parent)
- : QWidget(parent),
- m_angle(0),
- m_timerId(-1),
- m_delay(40),
- m_displayedWhenStopped(false),
- m_color(Qt::black)
-{
- setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
- setFocusPolicy(Qt::NoFocus);
-}
-
-bool QProgressIndicator::isAnimated () const
-{
- return (m_timerId != -1);
-}
-
-void QProgressIndicator::setDisplayedWhenStopped(bool state)
-{
- m_displayedWhenStopped = state;
-
- update();
-}
-
-bool QProgressIndicator::isDisplayedWhenStopped() const
-{
- return m_displayedWhenStopped;
-}
-
-void QProgressIndicator::startAnimation()
-{
- m_angle = 0;
-
- if (m_timerId == -1)
- m_timerId = startTimer(m_delay);
-}
-
-void QProgressIndicator::stopAnimation()
-{
- if (m_timerId != -1)
- killTimer(m_timerId);
-
- m_timerId = -1;
-
- update();
-}
-
-void QProgressIndicator::setAnimationDelay(int delay)
-{
- if (m_timerId != -1)
- killTimer(m_timerId);
-
- m_delay = delay;
-
- if (m_timerId != -1)
- m_timerId = startTimer(m_delay);
-}
-
-void QProgressIndicator::setColor(const QColor & color)
-{
- m_color = color;
-
- update();
-}
-
-QSize QProgressIndicator::sizeHint() const
-{
- return QSize(20,20);
-}
-
-int QProgressIndicator::heightForWidth(int w) const
-{
- return w;
-}
-
-void QProgressIndicator::timerEvent(QTimerEvent * /*event*/)
-{
- m_angle = (m_angle+30)%360;
-
- update();
-}
-
-void QProgressIndicator::paintEvent(QPaintEvent * /*event*/)
-{
- if (!m_displayedWhenStopped && !isAnimated())
- return;
-
- int width = qMin(this->width(), this->height());
-
- QPainter p(this);
- p.setRenderHint(QPainter::Antialiasing);
-
- int outerRadius = (width-1)*0.5;
- int innerRadius = (width-1)*0.5*0.38;
-
- int capsuleHeight = outerRadius - innerRadius;
- int capsuleWidth = (width > 32 ) ? capsuleHeight *.23 : capsuleHeight *.35;
- int capsuleRadius = capsuleWidth/2;
-
- for (int i=0; i<12; i++)
- {
- QColor color = m_color;
- color.setAlphaF(1.0f - (i/12.0f));
- p.setPen(Qt::NoPen);
- p.setBrush(color);
- p.save();
- p.translate(rect().center());
- p.rotate(m_angle - i*30.0f);
- p.drawRoundedRect(-capsuleWidth*0.5, -(innerRadius+capsuleHeight), capsuleWidth, capsuleHeight, capsuleRadius, capsuleRadius);
- p.restore();
- }
-}
diff --git a/kstars/ekos/QProgressIndicator.h b/kstars/ekos/QProgressIndicator.h
deleted file mode 100644
index 5baaa77..0000000
--- a/kstars/ekos/QProgressIndicator.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
-*
-* This file is part of QProgressIndicator,
-* an open-source recent files menu widget
-*
-* Copyright (C) 2009 - 2010 Morgan Leborgne
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Lesser General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public License
-* along with QRecentFilesMenu. If not, see <http://www.gnu.org/licenses/>.
-*
-*/
-#ifndef QPROGRESSINDICATOR_H
-#define QPROGRESSINDICATOR_H
-
-#include <QWidget>
-#include <QColor>
-
-/*!
- \class QProgressIndicator
- \brief The QProgressIndicator class lets an application display a progress indicator to show that a lengthy task is under way.
-
- Progress indicators are indeterminate and do nothing more than spin to show that the application is busy.
- \sa QProgressBar
-*/
-class QProgressIndicator : public QWidget
-{
- Q_OBJECT
- Q_PROPERTY(int delay READ animationDelay WRITE setAnimationDelay)
- Q_PROPERTY(bool displayedWhenStopped READ isDisplayedWhenStopped WRITE setDisplayedWhenStopped)
- Q_PROPERTY(QColor color READ color WRITE setColor)
-public:
- explicit QProgressIndicator(QWidget* parent = 0);
-
- /*! Returns the delay between animation steps.
- \return The number of milliseconds between animation steps. By default, the animation delay is set to 40 milliseconds.
- \sa setAnimationDelay
- */
- int animationDelay() const { return m_delay; }
-
- /*! Returns a Boolean value indicating whether the component is currently animated.
- \return Animation state.
- \sa startAnimation stopAnimation
- */
- bool isAnimated () const;
-
- /*! Returns a Boolean value indicating whether the receiver shows itself even when it is not animating.
- \return Return true if the progress indicator shows itself even when it is not animating. By default, it returns false.
- \sa setDisplayedWhenStopped
- */
- bool isDisplayedWhenStopped() const;
-
- /*! Returns the color of the component.
- \sa setColor
- */
- const QColor & color() const { return m_color; }
-
- virtual QSize sizeHint() const;
- int heightForWidth(int w) const;
-public slots:
- /*! Starts the spin animation.
- \sa stopAnimation isAnimated
- */
- void startAnimation();
-
- /*! Stops the spin animation.
- \sa startAnimation isAnimated
- */
- void stopAnimation();
-
- /*! Sets the delay between animation steps.
- Setting the \a delay to a value larger than 40 slows the animation, while setting the \a delay to a smaller value speeds it up.
- \param delay The delay, in milliseconds.
- \sa animationDelay
- */
- void setAnimationDelay(int delay);
-
- /*! Sets whether the component hides itself when it is not animating.
- \param state The animation state. Set false to hide the progress indicator when it is not animating; otherwise true.
- \sa isDisplayedWhenStopped
- */
- void setDisplayedWhenStopped(bool state);
-
- /*! Sets the color of the components to the given color.
- \sa color
- */
- void setColor(const QColor & color);
-protected:
- virtual void timerEvent(QTimerEvent * event);
- virtual void paintEvent(QPaintEvent * event);
-private:
- int m_angle;
- int m_timerId;
- int m_delay;
- bool m_displayedWhenStopped;
- QColor m_color;
-};
-
-#endif // QPROGRESSINDICATOR_H
diff --git a/kstars/ekos/align.cpp b/kstars/ekos/align.cpp
deleted file mode 100644
index ae15109..0000000
--- a/kstars/ekos/align.cpp
+++ /dev/null
@@ -1,1909 +0,0 @@
-/* Ekos Alignment Module
- Copyright (C) 2013 Jasem Mutlaq <mutlaqja@ikarustech.com>
-
- This application is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
- */
-
-#include <QProcess>
-
-#include "kstars.h"
-#include "kstarsdata.h"
-#include "align.h"
-#include "dms.h"
-#include "fov.h"
-#include "darklibrary.h"
-
-#include "Options.h"
-
-#include <QFileDialog>
-#include <KMessageBox>
-#include <KNotifications/KNotification>
-
-#include "QProgressIndicator.h"
-#include "indi/driverinfo.h"
-#include "indi/indicommon.h"
-#include "indi/clientmanager.h"
-#include "alignadaptor.h"
-
-#include "fitsviewer/fitsviewer.h"
-#include "fitsviewer/fitstab.h"
-#include "fitsviewer/fitsview.h"
-
-#include "ekosmanager.h"
-
-#include "onlineastrometryparser.h"
-#include "offlineastrometryparser.h"
-#include "remoteastrometryparser.h"
-
-#include <basedevice.h>
-
-#define MAXIMUM_SOLVER_ITERATIONS 10
-
-namespace Ekos
-{
-
-// 30 arcmiutes RA movement
-const double Align::RAMotion = 0.5;
-// Sidereal rate, degrees/s
-const float Align::SIDRATE = 0.004178;
-
-Align::Align()
-{
- setupUi(this);
- new AlignAdaptor(this);
- QDBusConnection::sessionBus().registerObject("/KStars/Ekos/Align", this);
-
- dirPath = QDir::homePath();
-
- state = ALIGN_IDLE;
- focusState = FOCUS_IDLE;
-
- currentCCD = NULL;
- currentTelescope = NULL;
- currentFilter = NULL;
- useGuideHead = false;
- canSync = false;
- //loadSlewMode = false;
- loadSlewState=IPS_IDLE;
- //m_isSolverComplete = false;
- //m_isSolverSuccessful = false;
- //m_slewToTargetSelected=false;
- m_wcsSynced=false;
- //isFocusBusy=false;
- ccd_hor_pixel = ccd_ver_pixel = focal_length = aperture = sOrientation = sRA = sDEC = -1;
- decDeviation = azDeviation = altDeviation = 0;
-
- rememberUploadMode = ISD::CCD::UPLOAD_CLIENT;
- currentFilter = NULL;
- filterPositionPending = false;
- lockedFilterIndex = currentFilterIndex = -1;
- retries=0;
- targetDiff=1e6;
- solverIterations=0;
- fov_x=fov_y=0;
-
- parser = NULL;
- solverFOV = new FOV();
- solverFOV->setColor(KStars::Instance()->data()->colorScheme()->colorNamed( "SolverFOVColor" ).name());
- onlineParser = NULL;
- offlineParser = NULL;
- remoteParser = NULL;
-
- connect(solveB, SIGNAL(clicked()), this, SLOT(captureAndSolve()));
- connect(stopB, SIGNAL(clicked()), this, SLOT(abort()));
- connect(measureAltB, SIGNAL(clicked()), this, SLOT(measureAltError()));
- connect(measureAzB, SIGNAL(clicked()), this, SLOT(measureAzError()));
- connect(polarR, SIGNAL(toggled(bool)), this, SLOT(checkPolarAlignment()));
- connect(raBox, SIGNAL(textChanged( const QString & ) ), this, SLOT( checkLineEdits() ) );
- connect(decBox, SIGNAL(textChanged( const QString & ) ), this, SLOT( checkLineEdits() ) );
- connect(syncBoxesB, SIGNAL(clicked()), this, SLOT(copyCoordsToBoxes()));
- connect(clearBoxesB, SIGNAL(clicked()), this, SLOT(clearCoordBoxes()));
-
- connect(CCDCaptureCombo, SIGNAL(activated(QString)), this, SLOT(setDefaultCCD(QString)));
- connect(CCDCaptureCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(checkCCD(int)));
-
- connect(correctAltB, SIGNAL(clicked()), this, SLOT(correctAltError()));
- connect(correctAzB, SIGNAL(clicked()), this, SLOT(correctAzError()));
- connect(loadSlewB, SIGNAL(clicked()), this, SLOT(loadAndSlew()));
-
- connect(gotoModeButtonGroup, static_cast<void (QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked), this, [=](int id){ this->currentGotoMode = static_cast<GotoMode>(id); });
-
- int i=0;
- foreach(QAbstractButton *button, gotoModeButtonGroup->buttons())
- gotoModeButtonGroup->setId(button, i++);
-
- currentGotoMode = static_cast<GotoMode>(Options::solverGotoOption());
- gotoModeButtonGroup->button(currentGotoMode)->setChecked(true);
-
- syncBoxesB->setIcon(QIcon::fromTheme("edit-copy"));
- clearBoxesB->setIcon(QIcon::fromTheme("edit-clear"));
-
- raBox->setDegType(false); //RA box should be HMS-style
-
- appendLogText(i18n("Idle."));
-
- pi = new QProgressIndicator(this);
-
- controlLayout->addWidget(pi, 0, 4, 1, 1);
-
- exposureIN->setValue(Options::alignExposure());
-
- altStage = ALT_INIT;
- azStage = AZ_INIT;
-
- // Online/Offline/Remote solver check
- solverTypeGroup->setId(onlineSolverR, SOLVER_ONLINE);
- solverTypeGroup->setId(offlineSolverR, SOLVER_OFFLINE);
- solverTypeGroup->setId(remoteSolverR, SOLVER_REMOTE);
- solverTypeGroup->button(Options::solverType())->setChecked(true);
- connect(solverTypeGroup, SIGNAL(buttonClicked(int)), SLOT(setSolverType(int)));
-
- switch(solverTypeGroup->checkedId())
- {
- case SOLVER_ONLINE:
- onlineParser = new Ekos::OnlineAstrometryParser();
- parser = onlineParser;
- break;
-
- case SOLVER_OFFLINE:
- offlineParser = new OfflineAstrometryParser();
- parser = offlineParser;
- break;
-
- case SOLVER_REMOTE:
- remoteParser = new RemoteAstrometryParser();
- parser = remoteParser;
- break;
- }
-
- parser->setAlign(this);
- if (parser->init() == false)
- setEnabled(false);
- else
- {
- connect(parser, SIGNAL(solverFinished(double,double,double, double)), this, SLOT(solverFinished(double,double,double, double)));
- connect(parser, SIGNAL(solverFailed()), this, SLOT(solverFailed()));
- }
-
- solverOptions->setText(Options::solverOptions());
-
- // Which telescope info to use for FOV calculations
- kcfg_solverOTA->setChecked(Options::solverOTA());
- connect(kcfg_solverOTA, SIGNAL(toggled(bool)), this, SLOT(syncTelescopeInfo()));
-
- accuracySpin->setValue(Options::solverAccuracyThreshold());
- alignDarkFrameCheck->setChecked(Options::alignDarkFrame());
-
- delaySpin->setValue(Options::settlingTime());
- connect(delaySpin, SIGNAL(editingFinished()), this, SLOT(saveSettleTime()));
-
- connect(binningCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(setBinningIndex(int)));
-}
-
-Align::~Align()
-{
- delete(pi);
- delete(solverFOV);
- delete(parser);
-}
-
-bool Align::isParserOK()
-{
- bool rc = parser->init();
-
- if (rc)
- {
- connect(parser, SIGNAL(solverFinished(double,double,double)), this, SLOT(solverFinished(double,double,double)));
- connect(parser, SIGNAL(solverFailed()), this, SLOT(solverFailed()));
- }
-
- return rc;
-}
-
-void Align::setSolverType(int type)
-{
- switch(type)
- {
- case SOLVER_ONLINE:
- if (onlineParser != NULL)
- {
- parser = onlineParser;
- return;
- }
-
- onlineParser = new Ekos::OnlineAstrometryParser();
- parser = onlineParser;
- break;
-
- case SOLVER_OFFLINE:
- if (offlineParser != NULL)
- {
- parser = offlineParser;
-
- return;
- }
-
- offlineParser = new Ekos::OfflineAstrometryParser();
- parser = offlineParser;
- break;
-
- case SOLVER_REMOTE:
- if (remoteParser != NULL)
- {
- parser = remoteParser;
- (dynamic_cast<RemoteAstrometryParser*>(parser))->setCCD(currentCCD);
- return;
- }
-
- remoteParser = new Ekos::RemoteAstrometryParser();
- parser = remoteParser;
- (dynamic_cast<RemoteAstrometryParser*>(parser))->setCCD(currentCCD);
- break;
- }
-
- parser->setAlign(this);
- if (parser->init())
- {
- connect(parser, SIGNAL(solverFinished(double,double,double, double)), this, SLOT(solverFinished(double,double,double, double)));
- connect(parser, SIGNAL(solverFailed()), this, SLOT(solverFailed()));
- }
- else
- parser->disconnect();
-
-}
-
-bool Align::setCCD(QString device)
-{
- for (int i=0; i < CCDCaptureCombo->count(); i++)
- if (device == CCDCaptureCombo->itemText(i))
- {
- CCDCaptureCombo->setCurrentIndex(i);
- return true;
- }
-
- return false;
-}
-
-void Align::setDefaultCCD(QString ccd)
-{
- Options::setDefaultAlignCCD(ccd);
-}
-
-void Align::checkCCD(int ccdNum)
-{
- if (ccdNum == -1)
- {
- ccdNum = CCDCaptureCombo->currentIndex();
-
- if (ccdNum == -1)
- return;
- }
-
- if (ccdNum <= CCDs.count())
- {
- currentCCD = CCDs.at(ccdNum);
-
- if (solverTypeGroup->checkedId() == SOLVER_REMOTE)
- (dynamic_cast<RemoteAstrometryParser*>(parser))->setCCD(currentCCD);
- }
-
- syncCCDInfo();
-
-}
-
-void Align::addCCD(ISD::GDInterface *newCCD)
-{
- if (CCDs.contains(static_cast<ISD::CCD *>(newCCD)))
- {
- syncCCDInfo();
- return;
- }
-
- CCDs.append(static_cast<ISD::CCD *>(newCCD));
-
- CCDCaptureCombo->addItem(newCCD->getDeviceName());
-}
-
-void Align::setTelescope(ISD::GDInterface *newTelescope)
-{
- currentTelescope = static_cast<ISD::Telescope*> (newTelescope);
-
- connect(currentTelescope, SIGNAL(numberUpdated(INumberVectorProperty*)), this, SLOT(processTelescopeNumber(INumberVectorProperty*)));
-
- syncTelescopeInfo();
-}
-
-void Align::syncTelescopeInfo()
-{
- INumberVectorProperty * nvp = currentTelescope->getBaseDevice()->getNumber("TELESCOPE_INFO");
-
- if (nvp)
- {
- INumber *np = NULL;
-
- if (kcfg_solverOTA->isChecked())
- np = IUFindNumber(nvp, "GUIDER_APERTURE");
- else
- np = IUFindNumber(nvp, "TELESCOPE_APERTURE");
-
- if (np && np->value > 0)
- aperture = np->value;
-
- if (kcfg_solverOTA->isChecked())
- np = IUFindNumber(nvp, "GUIDER_FOCAL_LENGTH");
- else
- np = IUFindNumber(nvp, "TELESCOPE_FOCAL_LENGTH");
-
- if (np && np->value > 0)
- focal_length = np->value;
- }
-
- if (focal_length == -1 || aperture == -1)
- return;
-
- if (ccd_hor_pixel != -1 && ccd_ver_pixel != -1 && focal_length != -1 && aperture != -1)
- calculateFOV();
-
- if (currentCCD && currentTelescope)
- generateArgs();
-
- if (syncR->isEnabled() && (canSync = currentTelescope->canSync()) == false)
- {
- syncR->setEnabled(false);
- slewR->setChecked(true);
- appendLogText(i18n("Telescope does not support syncing."));
- }
-}
-
-
-void Align::syncCCDInfo()
-{
- INumberVectorProperty * nvp = NULL;
- int x,y;
-
- if (currentCCD == NULL)
- return;
-
- if (useGuideHead)
- nvp = currentCCD->getBaseDevice()->getNumber("GUIDER_INFO");
- else
- nvp = currentCCD->getBaseDevice()->getNumber("CCD_INFO");
-
- if (nvp)
- {
- INumber *np = IUFindNumber(nvp, "CCD_PIXEL_SIZE_X");
- if (np && np->value >0)
- ccd_hor_pixel = ccd_ver_pixel = np->value;
-
- np = IUFindNumber(nvp, "CCD_PIXEL_SIZE_Y");
- if (np && np->value >0)
- ccd_ver_pixel = np->value;
-
- np = IUFindNumber(nvp, "CCD_PIXEL_SIZE_Y");
- if (np && np->value >0)
- ccd_ver_pixel = np->value;
- }
-
- ISD::CCDChip *targetChip = currentCCD->getChip(useGuideHead ? ISD::CCDChip::GUIDE_CCD : ISD::CCDChip::PRIMARY_CCD);
-
- ISwitchVectorProperty *svp = currentCCD->getBaseDevice()->getSwitch("WCS_CONTROL");
- if (svp)
- setWCSEnabled(Options::solverWCS());
-
- targetChip->getFrame(&x,&y,&ccd_width,&ccd_height);
- binningCombo->setEnabled(targetChip->canBin());
- if (targetChip->canBin())
- {
- binningCombo->blockSignals(true);
-
- int binx=1,biny=1;
- targetChip->getMaxBin(&binx, &biny);
- binningCombo->clear();
-
- for (int i=0; i < binx; i++)
- binningCombo->addItem(QString("%1x%2").arg(i+1).arg(i+1));
-
- binningCombo->setCurrentIndex(Options::solverBinningIndex());
-
- binningCombo->blockSignals(false);
- }
-
- if (ccd_hor_pixel == -1 || ccd_ver_pixel == -1)
- return;
-
- if (ccd_hor_pixel != -1 && ccd_ver_pixel != -1 && focal_length != -1 && aperture != -1)
- calculateFOV();
-
- if (currentCCD && currentTelescope)
- generateArgs();
-
-}
-
-
-void Align::calculateFOV()
-{
- // Calculate FOV
- fov_x = 206264.8062470963552 * ccd_width * ccd_hor_pixel / 1000.0 / focal_length;
- fov_y = 206264.8062470963552 * ccd_height * ccd_ver_pixel / 1000.0 / focal_length;
-
- fov_x /= 60.0;
- fov_y /= 60.0;
-
- solverFOV->setSize(fov_x, fov_y);
-
- FOVOut->setText(QString("%1' x %2'").arg(fov_x, 0, 'g', 3).arg(fov_y, 0, 'g', 3));
-
-}
-
-void Align::generateArgs()
-{
- // -O overwrite
- // -3 Expected RA
- // -4 Expected DEC
- // -5 Radius (deg)
- // -L lower scale of image in arcminutes
- // -H upper scale of image in arcmiutes
- // -u aw set scale to be in arcminutes
- // -W solution.wcs name of solution file
- // apog1.jpg name of target file to analyze
- //solve-field -O -3 06:40:51 -4 +09:49:53 -5 1 -L 40 -H 100 -u aw -W solution.wcs apod1.jpg
-
- double ra=0,dec=0, fov_lower, fov_upper;
- QString ra_dms, dec_dms;
- QString fov_low,fov_high;
- QStringList solver_args;
-
- // let's stretch the boundaries by 5%
- fov_lower = ((fov_x < fov_y) ? (fov_x *0.95) : (fov_y *0.95));
- fov_upper = ((fov_x > fov_y) ? (fov_x * 1.05) : (fov_y * 1.05));
-
- currentTelescope->getEqCoords(&ra, &dec);
-
- fov_low = QString("%1").arg(fov_lower);
- fov_high = QString("%1").arg(fov_upper);
-
- getFormattedCoords(ra, dec, ra_dms, dec_dms);
-
- if (solverOptions->text().isEmpty())
- {
- solver_args << "--no-verify" << "--no-plots" << "--no-fits2fits" << "--resort"
- << "--downsample" << "2" << "-O" << "-L" << fov_low << "-H" << fov_high << "-u" << "aw";
- }
- else
- {
- solver_args = solverOptions->text().split(" ");
- int fov_low_index = solver_args.indexOf("-L");
- if (fov_low_index != -1)
- solver_args.replace(fov_low_index+1, fov_low);
- int fov_high_index = solver_args.indexOf("-H");
- if (fov_high_index != -1)
- solver_args.replace(fov_high_index+1, fov_high);
- }
-
- if (raBox->isEmpty() == false && decBox->isEmpty() == false)
- {
- bool raOk(false), decOk(false), radiusOk(false);
- dms ra( raBox->createDms( false, &raOk ) ); //false means expressed in hours
- dms dec( decBox->createDms( true, &decOk ) );
- int radius = 30;
- QString message;
-
- if ( raOk && decOk )
- {
- //make sure values are in valid range
- if ( ra.Hours() < 0.0 || ra.Hours() > 24.0 )
- message = i18n( "The Right Ascension value must be between 0.0 and 24.0." );
- if ( dec.Degrees() < -90.0 || dec.Degrees() > 90.0 )
- message += '\n' + i18n( "The Declination value must be between -90.0 and 90.0." );
- if ( ! message.isEmpty() )
- {
- KMessageBox::sorry( 0, message, i18n( "Invalid Coordinate Data" ) );
- return;
- }
- }
-
- if (radiusBox->text().isEmpty() == false)
- radius = radiusBox->text().toInt(&radiusOk);
-
- if (radiusOk == false)
- {
- KMessageBox::sorry( 0, message, i18n( "Invalid radius value" ) );
- return;
- }
-
- int ra_index = solver_args.indexOf("-3");
- if (ra_index == -1)
- solver_args << "-3" << QString().setNum(ra.Degrees());
- else
- solver_args.replace(ra_index+1, QString().setNum(ra.Degrees()));
-
- int de_index = solver_args.indexOf("-4");
- if (de_index == -1)
- solver_args << "-4" << QString().setNum(dec.Degrees());
- else
- solver_args.replace(de_index+1, QString().setNum(dec.Degrees()));
-
- int rad_index = solver_args.indexOf("-5");
- if (rad_index == -1)
- solver_args << "-5" << QString().setNum(radius);
- else
- solver_args.replace(rad_index+1, QString().setNum(radius));
-
- }
-
- solverOptions->setText(solver_args.join(" "));
-}
-
-void Align::checkLineEdits()
-{
- bool raOk(false), decOk(false);
- raBox->createDms( false, &raOk );
- decBox->createDms( true, &decOk );
- if ( raOk && decOk )
- generateArgs();
-}
-
-void Align::copyCoordsToBoxes()
-{
- raBox->setText(ScopeRAOut->text());
- decBox->setText(ScopeDecOut->text());
-
- checkLineEdits();
-}
-
-void Align::clearCoordBoxes()
-{
- raBox->clear();
- decBox->clear();
-
- generateArgs();
-}
-
-bool Align::captureAndSolve()
-{
- //m_isSolverComplete = false;
-
- if (currentCCD == NULL)
- return false;
-
- if (parser->init() == false)
- return false;
-
- if (focal_length == -1 || aperture == -1)
- {
- KMessageBox::error(0, i18n("Telescope aperture and focal length are missing. Please check your driver settings and try again."));
- return false;
- }
-
- if (ccd_hor_pixel == -1 || ccd_ver_pixel == -1)
- {
- KMessageBox::error(0, i18n("CCD pixel size is missing. Please check your driver settings and try again."));
- return false;
- }
-
- if (currentFilter != NULL && lockedFilterIndex != -1)
- {
- if (lockedFilterIndex != currentFilterIndex)
- {
- int lockedFilterPosition = lockedFilterIndex + 1;
- filterPositionPending = true;
- currentFilter->runCommand(INDI_SET_FILTER, &lockedFilterPosition);
- return true;
- }
- }
-
- double seqExpose = exposureIN->value();
-
- ISD::CCDChip *targetChip = currentCCD->getChip(useGuideHead ? ISD::CCDChip::GUIDE_CCD : ISD::CCDChip::PRIMARY_CCD);
-
- if (focusState >= FOCUS_PROGRESS)
- {
- appendLogText(i18n("Cannot capture while focus module is busy! Retrying..."));
- QTimer::singleShot(1000, this, SLOT(captureAndSolve()));
- return false;
- }
-
- if (targetChip->isCapturing())
- {
- appendLogText(i18n("Cannot capture while CCD exposure is in progress! Retrying..."));
- QTimer::singleShot(1000, this, SLOT(captureAndSolve()));
- return false;
- }
-
- if (currentCCD->isConnected() == false)
- {
- appendLogText(i18n("Error: Lost connection to CCD."));
- KNotification::event( QLatin1String( "AlignFailed"), i18n("Astrometry alignment failed") );
- return false;
- }
-
- connect(currentCCD, SIGNAL(BLOBUpdated(IBLOB*)), this, SLOT(newFITS(IBLOB*)));
- connect(currentCCD, SIGNAL(newExposureValue(ISD::CCDChip*,double,IPState)), this, SLOT(checkCCDExposureProgress(ISD::CCDChip*,double,IPState)));
-
- // In case of remote solver, we set mode to UPLOAD_BOTH
- if (solverTypeGroup->checkedId() == SOLVER_REMOTE)
- {
- rememberUploadMode = currentCCD->getUploadMode();
- currentCCD->setUploadMode(ISD::CCD::UPLOAD_BOTH);
-
- // For solver remote we need to start solver BEFORE capture
- startSolving(QString());
- }
- else
- {
- if (currentCCD->getUploadMode() == ISD::CCD::UPLOAD_LOCAL)
- {
- rememberUploadMode = ISD::CCD::UPLOAD_LOCAL;
- currentCCD->setUploadMode(ISD::CCD::UPLOAD_CLIENT);
- }
- }
-
- targetChip->resetFrame();
- targetChip->setBatchMode(false);
- targetChip->setCaptureMode(FITS_ALIGN);
- targetChip->setFrameType(FRAME_LIGHT);
-
- int bin = Options::solverBinningIndex()+1;
- targetChip->setBinning(bin, bin);
-
- targetChip->capture(seqExpose);
-
- Options::setAlignExposure(seqExpose);
-
- solveB->setEnabled(false);
- stopB->setEnabled(true);
- pi->startAnimation();
-
- state = ALIGN_PROGRESS;
- emit newStatus(state);
-
- appendLogText(i18n("Capturing image..."));
-
- return true;
-}
-
-void Align::newFITS(IBLOB *bp)
-{
- // Ignore guide head if there is any.
- if (!strcmp(bp->name, "CCD2"))
- return;
-
- disconnect(currentCCD, SIGNAL(BLOBUpdated(IBLOB*)), this, SLOT(newFITS(IBLOB*)));
- disconnect(currentCCD, SIGNAL(newExposureValue(ISD::CCDChip*,double,IPState)), this, SLOT(checkCCDExposureProgress(ISD::CCDChip*,double,IPState)));
-
- appendLogText(i18n("Image received."));
-
- if (solverTypeGroup->checkedId() != SOLVER_REMOTE)
- {
- ISD::CCDChip *targetChip = currentCCD->getChip(useGuideHead ? ISD::CCDChip::GUIDE_CCD : ISD::CCDChip::PRIMARY_CCD);
-
- if (alignDarkFrameCheck->isChecked())
- {
- int x,y,w,h,binx=1,biny=1;
- targetChip->getFrame(&x,&y,&w,&h);
- targetChip->getBinning(&binx, &biny);
-
- FITSView *currentImage = targetChip->getImage(FITS_ALIGN);
- FITSData *darkData = NULL;
-
- uint16_t offsetX = x / binx;
- uint16_t offsetY = y / biny;
-
- darkData = DarkLibrary::Instance()->getDarkFrame(targetChip, exposureIN->value());
-
- connect(DarkLibrary::Instance(), SIGNAL(darkFrameCompleted(bool)), this, SLOT(setCaptureComplete()));
- connect(DarkLibrary::Instance(), SIGNAL(newLog(QString)), this, SLOT(appendLogText(QString)));
-
- if (darkData)
- DarkLibrary::Instance()->subtract(darkData, currentImage, FITS_NONE, offsetX, offsetY);
- else
- DarkLibrary::Instance()->captureAndSubtract(targetChip, currentImage, exposureIN->value(), offsetX, offsetY);
-
- return;
- }
-
- setCaptureComplete();
- }
-}
-
-void Align::setCaptureComplete()
-{
- DarkLibrary::Instance()->disconnect(this);
-
- ISD::CCDChip *targetChip = currentCCD->getChip(useGuideHead ? ISD::CCDChip::GUIDE_CCD : ISD::CCDChip::PRIMARY_CCD);
- FITSView *currentImage = targetChip->getImage(FITS_ALIGN);
- FITSData *currentData = currentImage->getImageData();
-
- QString filename = currentData->getFilename();
-
- // Save frame after subtraction
- if (alignDarkFrameCheck->isChecked())
- currentImage->getImageData()->saveFITS(filename);
-
- startSolving(filename);
-}
-
-void Align::setGOTOMode(int mode)
-{
- gotoModeButtonGroup->button(mode)->setChecked(true);
-}
-
-void Align::startSolving(const QString &filename, bool isGenerated)
-{
- QStringList solverArgs;
- double ra,dec;
-
- currentTelescope->getEqCoords(&ra, &dec);
-
- if (solverIterations == 0)
- {
- targetCoord.setRA(ra);
- targetCoord.setDec(dec);
- }
-
- Options::setSolverType(solverTypeGroup->checkedId());
- Options::setSolverOptions(solverOptions->text());
- Options::setSolverOTA(kcfg_solverOTA->isChecked());
- Options::setSolverAccuracyThreshold(accuracySpin->value());
- Options::setAlignDarkFrame(alignDarkFrameCheck->isChecked());
- Options::setSolverGotoOption(currentGotoMode);
-
- //m_isSolverComplete = false;
- //m_isSolverSuccessful = false;
-
- parser->verifyIndexFiles(fov_x, fov_y);
-
- solverTimer.start();
-
- if (isGenerated)
- solverArgs = solverOptions->text().split(" ");
- else if (filename.endsWith("fits") || filename.endsWith("fit"))
- {
- solverArgs = getSolverOptionsFromFITS(filename);
- appendLogText(i18n("Using solver options: %1", solverArgs.join(" ")));
- }
- else
- solverArgs << "--no-verify" << "--no-plots" << "--no-fits2fits" << "--resort" << "--downsample" << "2" << "-O";
-
- if (currentGotoMode == GOTO_SLEW)
- appendLogText(i18n("Solver iteration #%1", solverIterations+1));
-
- state = ALIGN_PROGRESS;
- emit newStatus(state);
-
- parser->startSovler(filename, solverArgs, isGenerated);
-}
-
-void Align::solverFinished(double orientation, double ra, double dec, double pixscale)
-{
- pi->stopAnimation();
- stopB->setEnabled(false);
- solveB->setEnabled(true);
-
- sOrientation = orientation;
- sRA = ra;
- sDEC = dec;
-
- int binx, biny;
- ISD::CCDChip *targetChip = currentCCD->getChip(useGuideHead ? ISD::CCDChip::GUIDE_CCD : ISD::CCDChip::PRIMARY_CCD);
- targetChip->getBinning(&binx, &biny);
-
- if (Options::solverVerbose())
- appendLogText(i18n("Solver RA (%1) DEC (%2) Orientation (%3) Pixel Scale (%4)", QString::number(ra, 'g' , 5), QString::number(dec, 'g' , 5),
- QString::number(orientation, 'g' , 5), QString::number(pixscale, 'g' , 5)));
-
- if (pixscale > 0 && loadSlewState == IPS_IDLE)
- {
- double solver_focal_length = (206.264 * ccd_hor_pixel) / pixscale * binx;
- if (fabs(focal_length - solver_focal_length) > 1)
- appendLogText(i18n("Current focal length is %1 mm while computed focal length from the solver is %2 mm. Please update the mount focal length to obtain accurate results.",
- QString::number(focal_length, 'g' , 5), QString::number(solver_focal_length, 'g' , 5)));
- }
-
- alignCoord.setRA0(ra/15.0);
- alignCoord.setDec0(dec);
- RotOut->setText(QString::number(orientation, 'g', 5));
-
- // Convert to JNow
- alignCoord.apparentCoord((long double) J2000, KStars::Instance()->data()->ut().djd());
- // Get horizontal coords
- alignCoord.EquatorialToHorizontal(KStarsData::Instance()->lst(), KStarsData::Instance()->geo()->lat());
-
- double raDiff = (alignCoord.ra().Degrees()-targetCoord.ra().Degrees()) * 3600;
- double deDiff = (alignCoord.dec().Degrees()-targetCoord.dec().Degrees()) * 3600;
-
- emit newSolutionDeviation(raDiff, deDiff);
-
- targetDiff = sqrt(raDiff*raDiff + deDiff*deDiff);
-
- solverFOV->setCenter(alignCoord);
- solverFOV->setRotation(sOrientation);
- solverFOV->setImageDisplay(Options::solverOverlay());
-
- QString ra_dms, dec_dms;
- getFormattedCoords(alignCoord.ra().Hours(), alignCoord.dec().Degrees(), ra_dms, dec_dms);
-
- SolverRAOut->setText(ra_dms);
- SolverDecOut->setText(dec_dms);
-
- if (Options::solverWCS())
- {
- INumberVectorProperty *ccdRotation = currentCCD->getBaseDevice()->getNumber("CCD_ROTATION");
- if (ccdRotation)
- {
- INumber *rotation = IUFindNumber(ccdRotation, "CCD_ROTATION_VALUE");
- if (rotation)
- {
- ClientManager *clientManager = currentCCD->getDriverInfo()->getClientManager();
- rotation->value = orientation;
- clientManager->sendNewNumber(ccdRotation);
-
- if (m_wcsSynced == false)
- {
- appendLogText(i18n("WCS information updated. Images captured from this point forward shall have valid WCS."));
-
- // Just send telescope info in case the CCD driver did not pick up before.
- INumberVectorProperty *telescopeInfo = currentTelescope->getBaseDevice()->getNumber("TELESCOPE_INFO");
- if (telescopeInfo)
- clientManager->sendNewNumber(telescopeInfo);
-
- m_wcsSynced=true;
- }
- }
- }
- }
-
- retries=0;
-
- appendLogText(i18n("Solution coordinates: RA (%1) DEC (%2) Telescope Coordinates: RA (%3) DEC (%4)", alignCoord.ra().toHMSString(), alignCoord.dec().toDMSString(), telescopeCoord.ra().toHMSString(), telescopeCoord.dec().toDMSString()));
- if (loadSlewState == IPS_IDLE && currentGotoMode == GOTO_SLEW)
- {
- dms diffDeg(targetDiff/3600.0);
- appendLogText(i18n("Target is within %1 degrees of solution coordinates.", diffDeg.toDMSString()));
- }
-
- if (rememberUploadMode != currentCCD->getUploadMode())
- currentCCD->setUploadMode(rememberUploadMode);
-
- //if (syncR->isChecked() || nothingR->isChecked() || targetDiff <= accuracySpin->value())
- // CONTINUE HERE
-
- switch (currentGotoMode)
- {
- case GOTO_SYNC:
- executeMode();
- break;
-
- case GOTO_SLEW:
- if (targetDiff > accuracySpin->value())
- {
- if (loadSlewState == IPS_IDLE && ++solverIterations == MAXIMUM_SOLVER_ITERATIONS)
- {
- appendLogText(i18n("Maximum number of iterations reached. Solver failed."));
- solverFailed();
- return;
- }
-
- //executeMode();
- executeGOTO();
- return;
- }
-
- appendLogText(i18n("Target is within acceptable range. Astrometric solver is successful."));
- break;
-
- case GOTO_NOTHING:
- break;
-
- }
-
- KNotification::event( QLatin1String( "AlignSuccessful"), i18n("Astrometry alignment completed successfully") );
- state = ALIGN_COMPLETE;
- emit newStatus(state);
- solverIterations=0;
-
- if (polarR->isChecked())
- executePolarAlign();
-}
-
-void Align::solverFailed()
-{
- KNotification::event( QLatin1String( "AlignFailed"), i18n("Astrometry alignment failed with errors") );
-
- pi->stopAnimation();
- stopB->setEnabled(false);
- solveB->setEnabled(true);
-
- azStage = AZ_INIT;
- altStage = ALT_INIT;
-
- //loadSlewMode = false;
- loadSlewState=IPS_IDLE;
- //m_isSolverComplete = true;
- //m_isSolverSuccessful = false;
- //m_slewToTargetSelected=false;
- solverIterations=0;
- retries=0;
-
- //emit solverComplete(false);
-
- state = ALIGN_FAILED;
- emit newStatus(state);
-}
-
-void Align::abort()
-{
- parser->stopSolver();
- pi->stopAnimation();
- stopB->setEnabled(false);
- solveB->setEnabled(true);
-
- azStage = AZ_INIT;
- altStage = ALT_INIT;
-
- //loadSlewMode = false;
- loadSlewState=IPS_IDLE;
- //m_isSolverComplete = false;
- //m_isSolverSuccessful = false;
- //m_slewToTargetSelected=false;
- solverIterations=0;
- retries=0;
-
- //currentCCD->disconnect(this);
- disconnect(currentCCD, SIGNAL(BLOBUpdated(IBLOB*)), this, SLOT(newFITS(IBLOB*)));
- disconnect(currentCCD, SIGNAL(newExposureValue(ISD::CCDChip*,double,IPState)), this, SLOT(checkCCDExposureProgress(ISD::CCDChip*,double,IPState)));
-
- if (rememberUploadMode != currentCCD->getUploadMode())
- currentCCD->setUploadMode(rememberUploadMode);
-
- ISD::CCDChip *targetChip = currentCCD->getChip(useGuideHead ? ISD::CCDChip::GUIDE_CCD : ISD::CCDChip::PRIMARY_CCD);
-
- // If capture is still in progress, let's stop that.
- if (targetChip->isCapturing())
- {
- targetChip->abortExposure();
- appendLogText(i18n("Capture aborted."));
- }
- else
- {
- int elapsed = (int) round(solverTimer.elapsed()/1000.0);
- appendLogText(i18np("Solver aborted after %1 second.", "Solver aborted after %1 seconds", elapsed));
- }
-
- state = ALIGN_ABORTED;
- emit newStatus(state);
-}
-
-QList<double> Align::getSolutionResult()
-{
- QList<double> result;
-
- result << sOrientation << sRA << sDEC;
-
- return result;
-}
-
-void Align::appendLogText(const QString &text)
-{
- logText.insert(0, i18nc("log entry; %1 is the date, %2 is the text", "%1 %2", QDateTime::currentDateTime().toString("yyyy-MM-ddThh:mm:ss"), text));
-
- if (Options::alignmentLogging())
- qDebug() << "Alignment: " << text;
-
- emit newLog();
-}
-
-void Align::clearLog()
-{
- logText.clear();
- emit newLog();
-}
-
-void Align::processTelescopeNumber(INumberVectorProperty *coord)
-{
- QString ra_dms, dec_dms;
- static bool slew_dirty=false;
-
- if (!strcmp(coord->name, "EQUATORIAL_EOD_COORD"))
- {
- getFormattedCoords(coord->np[0].value, coord->np[1].value, ra_dms, dec_dms);
-
- telescopeCoord.setRA(coord->np[0].value);
- telescopeCoord.setDec(coord->np[1].value);
- telescopeCoord.EquatorialToHorizontal(KStarsData::Instance()->lst(), KStarsData::Instance()->geo()->lat());
-
- ScopeRAOut->setText(ra_dms);
- ScopeDecOut->setText(dec_dms);
-
- if (currentTelescope->isSlewing() && slew_dirty == false)
- slew_dirty = true;
- else if (currentTelescope->isSlewing() == false && slew_dirty)
- {
- slew_dirty = false;
- if (Options::solverUpdateCoords())
- copyCoordsToBoxes();
-
- if (state >= ALIGN_PROGRESS)
- {
- if (loadSlewState == IPS_BUSY)
- {
- loadSlewState = IPS_IDLE;
- QTimer::singleShot(delaySpin->value(), this, SLOT(captureAndSolve()));
- return;
- }
- else if (currentGotoMode == GOTO_SLEW && state == ALIGN_SLEWING)
- {
- appendLogText(i18n("Target accuracy is not met, running solver again..."));
- QTimer::singleShot(delaySpin->value(), this, SLOT(captureAndSolve()));
- return;
- }
- }
- }
-
- switch (azStage)
- {
- case AZ_SYNCING:
- if (currentTelescope->isSlewing())
- azStage=AZ_SLEWING;
- break;
-
- case AZ_SLEWING:
- if (currentTelescope->isSlewing() == false)
- {
- azStage = AZ_SECOND_TARGET;
- measureAzError();
- }
- break;
-
- case AZ_CORRECTING:
- if (currentTelescope->isSlewing() == false)
- {
- appendLogText(i18n("Slew complete. Please adjust azimuth knob until the target is in the center of the view."));
- azStage = AZ_INIT;
- }
- break;
-
- default:
- break;
- }
-
- switch (altStage)
- {
- case ALT_SYNCING:
- if (currentTelescope->isSlewing())
- altStage = ALT_SLEWING;
- break;
-
- case ALT_SLEWING:
- if (currentTelescope->isSlewing() == false)
- {
- altStage = ALT_SECOND_TARGET;
- measureAltError();
- }
- break;
-
- case ALT_CORRECTING:
- if (currentTelescope->isSlewing() == false)
- {
- appendLogText(i18n("Slew complete. Please adjust altitude knob until the target is in the center of the view."));
- altStage = ALT_INIT;
- }
- break;
- default:
- break;
- }
-
- }
-
-
- if (!strcmp(coord->name, "TELESCOPE_INFO"))
- syncTelescopeInfo();
-
-}
-
-void Align::executeMode()
-{
- if (gotoR->isChecked())
- executeGOTO();
- else
- executePolarAlign();
-}
-
-
-void Align::executeGOTO()
-{
- if (loadSlewState == IPS_BUSY)
- {
- //if (loadSlewIterations == loadSlewIterationsSpin->value())
- //loadSlewCoord = alignCoord;
-
- //targetCoord = loadSlewCoord;
- targetCoord = alignCoord;
- SlewToTarget();
- }
- else if (currentGotoMode == GOTO_SYNC)
- Sync();
- else if (currentGotoMode == GOTO_SLEW)
- SlewToTarget();
-}
-
-void Align::Sync()
-{
- if (currentTelescope->Sync(&alignCoord))
- appendLogText(i18n("Syncing to RA (%1) DEC (%2) is successful.", alignCoord.ra().toHMSString(), alignCoord.dec().toDMSString()));
- else
- appendLogText(i18n("Syncing failed."));
-
-}
-
-void Align::SlewToTarget()
-{
- //if (canSync && (loadSlewMode == false || (loadSlewMode == true && loadSlewIterations < loadSlewIterationsSpin->value() )))
- if (canSync && loadSlewState == IPS_IDLE)
- Sync();
-
- //m_slewToTargetSelected = slewR->isChecked();
-
- currentTelescope->Slew(&targetCoord);
-
- appendLogText(i18n("Slewing to target coordinates: RA (%1) DEC (%2).", targetCoord.ra().toHMSString(), targetCoord.dec().toDMSString()));
-
- state = ALIGN_SLEWING;
- emit newStatus(state);
-}
-
-void Align::checkPolarAlignment()
-{
- if (polarR->isChecked())
- {
- measureAltB->setEnabled(true);
- measureAzB->setEnabled(true);
- gotoBox->setEnabled(false);
- }
- else
- {
- measureAltB->setEnabled(false);
- measureAzB->setEnabled(false);
- gotoBox->setEnabled(true);
- }
-}
-
-void Align::executePolarAlign()
-{
- appendLogText(i18n("Processing solution for polar alignment..."));
-
- switch (azStage)
- {
- case AZ_FIRST_TARGET:
- case AZ_FINISHED:
- measureAzError();
- break;
-
- default:
- break;
- }
-
- switch (altStage)
- {
- case ALT_FIRST_TARGET:
- case ALT_FINISHED:
- measureAltError();
- break;
-
- default:
- break;
- }
-}
-
-
-void Align::measureAzError()
-{
- static double initRA=0, initDEC=0, finalRA=0, finalDEC=0, initAz=0;
- int hemisphere = KStarsData::Instance()->geo()->lat()->Degrees() > 0 ? 0 : 1;
-
- if (Options::alignmentLogging())
- qDebug() << "Polar Alignment: Measureing Azimuth Error...";
-
- switch (azStage)
- {
- case AZ_INIT:
-
- // Display message box confirming user point scope near meridian and south
-
- if (KMessageBox::warningContinueCancel( 0, hemisphere == 0
- ? i18n("Point the telescope at the southern meridian. Press continue when ready.")
- : i18n("Point the telescope at the northern meridian. Press continue when ready.")
- , i18n("Polar Alignment Measurement"), KStandardGuiItem::cont(), KStandardGuiItem::cancel(),
- "ekos_measure_az_error")!=KMessageBox::Continue)
- return;
-
- appendLogText(i18n("Solving first frame near the meridian."));
- azStage = AZ_FIRST_TARGET;
- polarR->setChecked(true);
- solveB->click();
- break;
-
- case AZ_FIRST_TARGET:
- // start solving there, find RA/DEC
- initRA = alignCoord.ra().Degrees();
- initDEC = alignCoord.dec().Degrees();
- initAz = alignCoord.az().Degrees();
-
- if (Options::alignmentLogging())
- qDebug() << "Polar Alignment: initRA " << alignCoord.ra().toHMSString() << " initDEC " << alignCoord.dec().toDMSString() <<
- " initlAz " << alignCoord.az().toDMSString() << " initAlt " << alignCoord.alt().toDMSString();
-
- // Now move 30 arcminutes in RA
- if (canSync)
- {
- azStage = AZ_SYNCING;
- currentTelescope->Sync(initRA/15.0, initDEC);
- currentTelescope->Slew((initRA - RAMotion)/15.0, initDEC);
- }
- // If telescope doesn't sync, we slew relative to its current coordinates
- else
- {
- azStage = AZ_SLEWING;
- currentTelescope->Slew(telescopeCoord.ra().Hours() - RAMotion/15.0, telescopeCoord.dec().Degrees());
- }
-
- appendLogText(i18n("Slewing 30 arcminutes in RA..."));
- break;
-
- case AZ_SECOND_TARGET:
- // We reached second target now
- // Let now solver for RA/DEC
- appendLogText(i18n("Solving second frame near the meridian."));
- azStage = AZ_FINISHED;
- polarR->setChecked(true);
- solveB->click();
- break;
-
-
- case AZ_FINISHED:
- // Measure deviation in DEC
- // Call function to report error
- // set stage to AZ_FIRST_TARGET again
- appendLogText(i18n("Calculating azimuth alignment error..."));
- finalRA = alignCoord.ra().Degrees();
- finalDEC = alignCoord.dec().Degrees();
-
- if (Options::alignmentLogging())
- qDebug() << "Polar Alignment: finalRA " << alignCoord.ra().toHMSString() << " finalDEC " << alignCoord.dec().toDMSString() <<
- " finalAz " << alignCoord.az().toDMSString() << " finalAlt " << alignCoord.alt().toDMSString();
-
- // Slew back to original position
- if (canSync)
- currentTelescope->Slew(initRA/15.0, initDEC);
- else
- {
- currentTelescope->Slew(telescopeCoord.ra().Hours() + RAMotion/15.0, telescopeCoord.dec().Degrees());
- }
-
- appendLogText(i18n("Slewing back to original position..."));
-
- calculatePolarError(initRA, initDEC, finalRA, finalDEC, initAz);
-
- azStage = AZ_INIT;
- break;
-
- default:
- break;
-
- }
-
-}
-
-void Align::measureAltError()
-{
- static double initRA=0, initDEC=0, finalRA=0, finalDEC=0, initAz=0;
-
- if (Options::alignmentLogging())
- qDebug() << "Polar Alignment: Measureing Altitude Error...";
-
- switch (altStage)
- {
- case ALT_INIT:
-
- // Display message box confirming user point scope near meridian and south
-
- if (KMessageBox::warningContinueCancel( 0, i18n("Point the telescope to the eastern or western horizon with a minimum altitude of 20 degrees. Press continue when ready.")
- , i18n("Polar Alignment Measurement"), KStandardGuiItem::cont(), KStandardGuiItem::cancel(),
- "ekos_measure_alt_error")!=KMessageBox::Continue)
- return;
-
- appendLogText(i18n("Solving first frame."));
- altStage = ALT_FIRST_TARGET;
- polarR->setChecked(true);
- solveB->click();
- break;
-
- case ALT_FIRST_TARGET:
- // start solving there, find RA/DEC
- initRA = alignCoord.ra().Degrees();
- initDEC = alignCoord.dec().Degrees();
- initAz = alignCoord.az().Degrees();
-
- if (Options::alignmentLogging())
- qDebug() << "Polar Alignment: initRA " << alignCoord.ra().toHMSString() << " initDEC " << alignCoord.dec().toDMSString() <<
- " initlAz " << alignCoord.az().toDMSString() << " initAlt " << alignCoord.alt().toDMSString();
-
- // Now move 30 arcminutes in RA
- if (canSync)
- {
- altStage = ALT_SYNCING;
- currentTelescope->Sync(initRA/15.0, initDEC);
- currentTelescope->Slew((initRA - RAMotion)/15.0, initDEC);
-
- }
- // If telescope doesn't sync, we slew relative to its current coordinates
- else
- {
- altStage = ALT_SLEWING;
- currentTelescope->Slew(telescopeCoord.ra().Hours() - RAMotion/15.0, telescopeCoord.dec().Degrees());
- }
-
-
- appendLogText(i18n("Slewing 30 arcminutes in RA..."));
- break;
-
- case ALT_SECOND_TARGET:
- // We reached second target now
- // Let now solver for RA/DEC
- appendLogText(i18n("Solving second frame."));
- altStage = ALT_FINISHED;
- polarR->setChecked(true);
- solveB->click();
- break;
-
-
- case ALT_FINISHED:
- // Measure deviation in DEC
- // Call function to report error
- appendLogText(i18n("Calculating altitude alignment error..."));
- finalRA = alignCoord.ra().Degrees();
- finalDEC = alignCoord.dec().Degrees();
-
- if (Options::alignmentLogging())
- qDebug() << "Polar Alignment: finalRA " << alignCoord.ra().toHMSString() << " finalDEC " << alignCoord.dec().toDMSString() <<
- " finalAz " << alignCoord.az().toDMSString() << " finalAlt " << alignCoord.alt().toDMSString();
-
- // Slew back to original position
- if (canSync)
- currentTelescope->Slew(initRA/15.0, initDEC);
- // If telescope doesn't sync, we slew relative to its current coordinates
- else
- {
- currentTelescope->Slew(telescopeCoord.ra().Hours() + RAMotion/15.0, telescopeCoord.dec().Degrees());
- }
-
- appendLogText(i18n("Slewing back to original position..."));
-
- calculatePolarError(initRA, initDEC, finalRA, finalDEC, initAz);
-
- altStage = ALT_INIT;
- break;
-
- default:
- break;
-
- }
-
-}
-
-void Align::calculatePolarError(double initRA, double initDEC, double finalRA, double finalDEC, double initAz)
-{
- double raMotion = finalRA - initRA;
- decDeviation = finalDEC - initDEC;
-
- // Northern/Southern hemisphere
- int hemisphere = KStarsData::Instance()->geo()->lat()->Degrees() > 0 ? 0 : 1;
- // East/West of meridian
- int horizon = (initAz > 0 && initAz <= 180) ? 0 : 1;
-
- // How much time passed siderrally form initRA to finalRA?
- //double RATime = fabs(raMotion / SIDRATE) / 60.0;
-
- // 2016-03-30: Diff in RA is sufficient for time difference
- // raMotion in degrees. RATime in minutes.
- double RATime = fabs(raMotion) * 60.0;
-
- // Equation by Frank Berret (Measuring Polar Axis Alignment Error, page 4)
- // In degrees
- double deviation = (3.81 * (decDeviation * 3600) ) / ( RATime * cos(initDEC * dms::DegToRad)) / 60.0;
- dms devDMS(fabs(deviation));
-
- KLocalizedString deviationDirection;
-
- switch (hemisphere)
- {
- // Northern hemisphere
- case 0:
- if (azStage == AZ_FINISHED)
- {
- if (decDeviation > 0)
- deviationDirection = ki18n("%1 too far east");
- else
- deviationDirection = ki18n("%1 too far west");
- }
- else if (altStage == ALT_FINISHED)
- {
- switch (horizon)
- {
- // East
- case 0:
- if (decDeviation > 0)
- deviationDirection = ki18n("%1 too far high");
- else
- deviationDirection = ki18n("%1 too far low");
-
- break;
-
- // West
- case 1:
- if (decDeviation > 0)
- deviationDirection = ki18n("%1 too far low");
- else
- deviationDirection = ki18n("%1 too far high");
- break;
-
- default:
- break;
- }
- }
- break;
-
- // Southern hemisphere
- case 1:
- if (azStage == AZ_FINISHED)
- {
- if (decDeviation > 0)
- deviationDirection = ki18n("%1 too far west");
- else
- deviationDirection = ki18n("%1 too far east");
- }
- else if (altStage == ALT_FINISHED)
- {
- switch (horizon)
- {
- // East
- case 0:
- if (decDeviation > 0)
- deviationDirection = ki18n("%1 too far low");
- else
- deviationDirection = ki18n("%1 too far high");
- break;
-
- // West
- case 1:
- if (decDeviation > 0)
- deviationDirection = ki18n("%1 too far high");
- else
- deviationDirection = ki18n("%1 too far low");
- break;
-
- default:
- break;
- }
- }
- break;
-
- default:
- break;
-
- }
-
- if (Options::alignmentLogging())
- {
- qDebug() << "Polar Alignment: Hemisphere is " << ((hemisphere == 0) ? "North" : "South") << " --- initAz " << initAz;
- qDebug() << "Polar Alignment: initRA " << initRA << " initDEC " << initDEC << " finalRA " << finalRA << " finalDEC " << finalDEC;
- qDebug() << "Polar Alignment: decDeviation " << decDeviation*3600 << " arcsec " << " RATime " << RATime << " minutes";
- qDebug() << "Polar Alignment: Raw Deviaiton " << deviation << " degrees.";
- }
-
- if (azStage == AZ_FINISHED)
- {
- azError->setText(deviationDirection.subs(QString("%1").arg(devDMS.toDMSString())).toString());
- //azError->setText(deviationDirection.subs(QString("%1")azDMS.toDMSString());
- azDeviation = deviation * (decDeviation > 0 ? 1 : -1);
-
- if (Options::alignmentLogging())
- qDebug() << "Polar Alignment: Azimuth Deviation " << azDeviation << " degrees.";
-
- correctAzB->setEnabled(true);
- }
- if (altStage == ALT_FINISHED)
- {
- //altError->setText(deviationDirection.subs(QString("%1").arg(fabs(deviation), 0, 'g', 3)).toString());
- altError->setText(deviationDirection.subs(QString("%1").arg(devDMS.toDMSString())).toString());
- altDeviation = deviation * (decDeviation > 0 ? 1 : -1);
-
- if (Options::alignmentLogging())
- qDebug() << "Polar Alignment: Altitude Deviation " << altDeviation << " degrees.";
-
- correctAltB->setEnabled(true);
- }
-}
-
-void Align::correctAltError()
-{
- double newRA, newDEC;
-
- SkyPoint currentCoord (telescopeCoord);
- dms targetLat;
-
- if (Options::alignmentLogging())
- {
- qDebug() << "Polar Alignment: Correcting Altitude Error...";
- qDebug() << "Polar Alignment: Current Mount RA " << currentCoord.ra().toHMSString() << " DEC " << currentCoord.dec().toDMSString() <<
- "Az " << currentCoord.az().toDMSString() << " Alt " << currentCoord.alt().toDMSString();
- }
-
- // An error in polar alignment altitude reflects a deviation in the latitude of the mount from actual latitude of the site
- // Calculating the latitude accounting for the altitude deviation. This is the latitude at which the altitude deviation should be zero.
- targetLat.setD(KStars::Instance()->data()->geo()->lat()->Degrees() + altDeviation);
-
- // Calculate the Az/Alt of the mount if it were located at the corrected latitude
- currentCoord.EquatorialToHorizontal(KStars::Instance()->data()->lst(), &targetLat );
-
- // Convert corrected Az/Alt to RA/DEC given the local sideral time and current (not corrected) latitude
- currentCoord.HorizontalToEquatorial(KStars::Instance()->data()->lst(), KStars::Instance()->data()->geo()->lat());
-
- // New RA/DEC should reflect the position in the sky at which the polar alignment altitude error is minimal.
- newRA = currentCoord.ra().Hours();
- newDEC = currentCoord.dec().Degrees();
-
- altStage = ALT_CORRECTING;
-
- if (Options::alignmentLogging())
- {
- qDebug() << "Polar Alignment: Target Latitude = Latitude " << KStars::Instance()->data()->geo()->lat()->Degrees() << " + Altitude Deviation " << altDeviation << " = " << targetLat.Degrees();
- qDebug() << "Polar Alignment: Slewing to calibration position...";
- }
-
- currentTelescope->Slew(newRA, newDEC);
-
- appendLogText(i18n("Slewing to calibration position, please wait until telescope completes slewing."));
-}
-
-void Align::correctAzError()
-{
- double newRA, newDEC, currentAlt, currentAz;
-
- SkyPoint currentCoord (telescopeCoord);
-
- if (Options::alignmentLogging())
- {
- qDebug() << "Polar Alignment: Correcting Azimuth Error...";
- qDebug() << "Polar Alignment: Current Mount RA " << currentCoord.ra().toHMSString() << " DEC " << currentCoord.dec().toDMSString() <<
- "Az " << currentCoord.az().toDMSString() << " Alt " << currentCoord.alt().toDMSString();
- qDebug() << "Polar Alignment: Target Azimuth = Current Azimuth " << currentCoord.az().Degrees() << " + Azimuth Deviation " << azDeviation << " = " << currentCoord.az().Degrees() + azDeviation;
- }
-
- // Get current horizontal coordinates of the mount
- currentCoord.EquatorialToHorizontal(KStars::Instance()->data()->lst(), KStars::Instance()->data()->geo()->lat());
-
- // Keep Altitude as it is and change Azimuth to account for the azimuth deviation
- // The new sky position should be where the polar alignment azimuth error is minimal
- currentAlt = currentCoord.alt().Degrees();
- currentAz = currentCoord.az().Degrees() + azDeviation;
-
- // Update current Alt and Azimuth to new values
- currentCoord.setAlt(currentAlt);
- currentCoord.setAz(currentAz);
-
- // Convert Alt/Az back to equatorial coordinates
- currentCoord.HorizontalToEquatorial(KStars::Instance()->data()->lst(), KStars::Instance()->data()->geo()->lat());
-
- // Get new RA and DEC
- newRA = currentCoord.ra().Hours();
- newDEC = currentCoord.dec().Degrees();
-
- azStage = AZ_CORRECTING;
-
- if (Options::alignmentLogging())
- qDebug() << "Polar Alignment: Slewing to calibration position...";
-
- currentTelescope->Slew(newRA, newDEC);
-
- appendLogText(i18n("Slewing to calibration position, please wait until telescope completes slewing."));
-
-}
-
-void Align::getFormattedCoords(double ra, double dec, QString &ra_str, QString &dec_str)
-{
- dms ra_s,dec_s;
- ra_s.setH(ra);
- dec_s.setD(dec);
-
- ra_str = QString("%1:%2:%3").arg(ra_s.hour(), 2, 10, QChar('0')).arg(ra_s.minute(), 2, 10, QChar('0')).arg(ra_s.second(), 2, 10, QChar('0'));
- if (dec_s.Degrees() < 0)
- dec_str = QString("-%1:%2:%3").arg(abs(dec_s.degree()), 2, 10, QChar('0')).arg(abs(dec_s.arcmin()), 2, 10, QChar('0')).arg(dec_s.arcsec(), 2, 10, QChar('0'));
- else
- dec_str = QString("%1:%2:%3").arg(dec_s.degree(), 2, 10, QChar('0')).arg(dec_s.arcmin(), 2, 10, QChar('0')).arg(dec_s.arcsec(), 2, 10, QChar('0'));
-}
-
-void Align::loadAndSlew(QString fileURL)
-{
- if (fileURL.isEmpty())
- fileURL = QFileDialog::getOpenFileName(KStars::Instance(), i18n("Load Image"), dirPath, "Images (*.fits *.fit *.jpg *.jpeg)");
-
- if (fileURL.isEmpty())
- return;
-
- QFileInfo fileInfo(fileURL);
- dirPath = fileInfo.absolutePath();
-
- //loadSlewMode = true;
- loadSlewState=IPS_BUSY;
-
- slewR->setChecked(true);
-
- solveB->setEnabled(false);
- stopB->setEnabled(true);
- pi->startAnimation();
-
- startSolving(fileURL, false);
-}
-
-void Align::setExposure(double value)
-{
- exposureIN->setValue(value);
-}
-
-void Align::setBinningIndex(int binIndex)
-{
- Options::setSolverBinningIndex(binIndex);
-
- // If sender is not our combo box, then we need to update the combobox itself
- if ( dynamic_cast<QComboBox*>(sender()) != binningCombo)
- {
- binningCombo->blockSignals(true);
- binningCombo->setCurrentIndex(binIndex);
- binningCombo->blockSignals(false);
- }
-}
-
-void Align::setSolverArguments(const QString & value)
-{
- solverOptions->setText(value);
-}
-
-void Align::setSolverSearchOptions(double ra, double dec, double radius)
-{
- dms RA, DEC;
- RA.setH(ra);
- DEC.setD(dec);
-
- raBox->setText(RA.toHMSString());
- decBox->setText(DEC.toDMSString());
- radiusBox->setText(QString::number(radius));
-}
-
-void Align::setUseOAGT(bool enabled)
-{
- kcfg_solverOTA->setChecked(enabled);
-}
-
-FOV* Align::fov()
-{
- if (sOrientation == -1)
- return NULL;
- else
- return solverFOV;
-
-}
-
-void Align::setLockedFilter(ISD::GDInterface *filter, int lockedPosition)
-{
- currentFilter = filter;
- if (currentFilter)
- {
- lockedFilterIndex = lockedPosition;
-
- INumberVectorProperty *filterSlot = filter->getBaseDevice()->getNumber("FILTER_SLOT");
- if (filterSlot)
- currentFilterIndex = filterSlot->np[0].value-1;
-
- connect(currentFilter, SIGNAL(numberUpdated(INumberVectorProperty*)), this, SLOT(processFilterNumber(INumberVectorProperty*)), Qt::UniqueConnection);
- }
-}
-
-void Align::processFilterNumber(INumberVectorProperty *nvp)
-{
- if (currentFilter && !strcmp(nvp->name, "FILTER_SLOT") && !strcmp(nvp->device, currentFilter->getDeviceName()))
- {
- currentFilterIndex = nvp->np[0].value - 1;
-
- if (filterPositionPending)
- {
- if (currentFilterIndex == lockedFilterIndex)
- {
- filterPositionPending = false;
- captureAndSolve();
- }
- }
- }
-}
-
-void Align::setWCSEnabled(bool enable)
-{
- if (currentCCD == NULL)
- return;
-
- ISwitchVectorProperty *wcsControl = currentCCD->getBaseDevice()->getSwitch("WCS_CONTROL");
-
- ISwitch *wcs_enable = IUFindSwitch(wcsControl, "WCS_ENABLE");
- ISwitch *wcs_disable = IUFindSwitch(wcsControl, "WCS_DISABLE");
-
- if (!wcs_enable || !wcs_disable)
- return;
-
- if ( (wcs_enable->s == ISS_ON && enable) || (wcs_disable->s == ISS_ON && !enable) )
- return;
-
- IUResetSwitch(wcsControl);
- if (enable)
- {
- appendLogText(i18n("World Coordinate System (WCS) is enabled. CCD rotation must be set either manually in the CCD driver or by solving an image before proceeding to capture any further images, otherwise the WCS information may be invalid."));
- wcs_enable->s = ISS_ON;
- }
- else
- {
- wcs_disable->s = ISS_ON;
- m_wcsSynced=false;
- appendLogText(i18n("World Coordinate System (WCS) is disabled."));
- }
-
- ClientManager *clientManager = currentCCD->getDriverInfo()->getClientManager();
-
- clientManager->sendNewSwitch(wcsControl);
-}
-
-void Align::checkCCDExposureProgress(ISD::CCDChip *targetChip, double remaining, IPState state)
-{
- INDI_UNUSED(targetChip);
- INDI_UNUSED(remaining);
-
- if (state == IPS_ALERT)
- {
- if (++retries == 3)
- {
- appendLogText(i18n("Capture error! Aborting..."));
-
- abort();
- return;
- }
-
- appendLogText(i18n("Restarting capture attempt #%1", retries));
- captureAndSolve();
- }
-}
-
-void Align::setFocusStatus(Ekos::FocusState state)
-{
- focusState = state;
-}
-
-QStringList Align::getSolverOptionsFromFITS(const QString &filename)
-{
- int status=0, fits_ccd_width, fits_ccd_height, fits_focal_length=-1, fits_binx=1, fits_biny=1;
- char comment[128], error_status[512];
- fitsfile * fptr = NULL;
- double ra=0,dec=0, fits_fov_x, fits_fov_y, fov_lower, fov_upper, fits_ccd_hor_pixel=-1, fits_ccd_ver_pixel=-1;
- QString fov_low,fov_high;
- QStringList solver_args;
-
- // Default arguments
- solver_args << "--no-verify" << "--no-plots" << "--no-fits2fits" << "--resort" << "--downsample" << "2" << "-O";
-
- if (fits_open_image(&fptr, filename.toLatin1(), READONLY, &status))
- {
- fits_report_error(stderr, status);
- fits_get_errstatus(status, error_status);
- qWarning() << "Could not open file " << filename << " Error: " << QString::fromUtf8(error_status);
- return solver_args;
- }
-
- if (fits_read_key(fptr, TINT, "NAXIS1", &fits_ccd_width, comment, &status ))
- {
- fits_report_error(stderr, status);
- fits_get_errstatus(status, error_status);
- appendLogText(i18n("FITS header: Cannot find NAXIS1."));
- return solver_args;
- }
-
- if (fits_read_key(fptr, TINT, "NAXIS2", &fits_ccd_height, comment, &status ))
- {
- fits_report_error(stderr, status);
- fits_get_errstatus(status, error_status);
- appendLogText(i18n("FITS header: Cannot find NAXIS2."));
- return solver_args;
- }
-
- bool coord_ok = true;
-
- if (fits_read_key(fptr, TDOUBLE, "OBJCTRA", &ra, comment, &status ))
- {
- fits_report_error(stderr, status);
- fits_get_errstatus(status, error_status);
- coord_ok=false;
- appendLogText(i18n("FITS header: Cannot find OBJCTRA. Using current mount coordinates."));
- //return solver_args;
- }
-
- if (coord_ok && fits_read_key(fptr, TDOUBLE, "OBJCTDEC", &dec, comment, &status ))
- {
- fits_report_error(stderr, status);
- fits_get_errstatus(status, error_status);
- coord_ok=false;
- appendLogText(i18n("FITS header: Cannot find OBJCTDEC. Using current mount coordinates."));
- //return solver_args;
- }
-
- if (coord_ok == false)
- {
- ra = telescopeCoord.ra0().Hours();
- dec = telescopeCoord.dec0().Degrees();
- }
-
- solver_args << "-3" << QString::number(ra*15.0) << "-4" << QString::number(dec) << "-5 15";
-
- if (fits_read_key(fptr, TINT, "FOCALLEN", &fits_focal_length, comment, &status ))
- {
- fits_report_error(stderr, status);
- fits_get_errstatus(status, error_status);
- appendLogText(i18n("FITS header: Cannot find FOCALLEN."));
- return solver_args;
- }
-
- if (fits_read_key(fptr, TDOUBLE, "PIXSIZE1", &fits_ccd_hor_pixel, comment, &status ))
- {
- fits_report_error(stderr, status);
- fits_get_errstatus(status, error_status);
- appendLogText(i18n("FITS header: Cannot find PIXSIZE1."));
- return solver_args;
- }
-
- if (fits_read_key(fptr, TDOUBLE, "PIXSIZE2", &fits_ccd_ver_pixel, comment, &status ))
- {
- fits_report_error(stderr, status);
- fits_get_errstatus(status, error_status);
- appendLogText(i18n("FITS header: Cannot find PIXSIZE2."));
- return solver_args;
- }
-
- fits_read_key(fptr, TINT, "XBINNING", &fits_binx, comment, &status );
- fits_read_key(fptr, TINT, "YBINNING", &fits_biny, comment, &status );
-
- // Calculate FOV
- fits_fov_x = 206264.8062470963552 * fits_ccd_width * fits_ccd_hor_pixel / 1000.0 / fits_focal_length * fits_binx;
- fits_fov_y = 206264.8062470963552 * fits_ccd_height * fits_ccd_ver_pixel / 1000.0 / fits_focal_length* fits_biny;
-
- fits_fov_x /= 60.0;
- fits_fov_y /= 60.0;
-
- // let's stretch the boundaries by 5%
- fov_lower = ((fits_fov_x < fits_fov_y) ? (fits_fov_x *0.95) : (fits_fov_y *0.95));
- fov_upper = ((fits_fov_x > fits_fov_y) ? (fits_fov_x * 1.05) : (fits_fov_y * 1.05));
-
- fov_low = QString::number(fov_lower);
- fov_high = QString::number(fov_upper);
-
- solver_args << "-L" << fov_low << "-H" << fov_high << "-u" << "aw";
-
-
- return solver_args;
-}
-
-void Align::saveSettleTime()
-{
- Options::setSettlingTime(delaySpin->value());
-}
-
-}
-
-
diff --git a/kstars/ekos/align.h b/kstars/ekos/align.h
deleted file mode 100644
index 1b25992..0000000
--- a/kstars/ekos/align.h
+++ /dev/null
@@ -1,460 +0,0 @@
-/* Ekos Polar Alignment Tool
- Copyright (C) 2013 Jasem Mutlaq <mutlaqja@ikarustech.com>
-
- This application is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
- */
-
-#ifndef ALIGN_H
-#define ALIGN_H
-
-#include <QProcess>
-#include <QTime>
-#include <QtDBus/QtDBus>
-
-#include <config-kstars.h>
-
-#include "capture.h"
-
-#include "ui_align.h"
-
-#include "indi/inditelescope.h"
-#include "indi/indistd.h"
-
-class FOV;
-
-namespace Ekos
-{
-
-class AstrometryParser;
-class OnlineAstrometryParser;
-class OfflineAstrometryParser;
-class RemoteAstrometryParser;
-
-/**
- *@class Align
- *@short Align class handles plate-solving and polar alignment measurement and correction using astrometry.net
- * The align class can capture images from the CCD and use either online or offline astrometry.net engine to solve the plate constants and find the center RA/DEC coordinates. The user selects the action
- * to perform when the solver completes successfully. Measurement of polar alignment errors is performed by capturing two images on selected points in the sky and measuring the declination drift to calculate
- * the error in the mount's azimutn and altitude displacement from optimal. Correction is carried by asking the user to re-center a star by adjusting the telescope's azimuth and/or altitude knobs.
- *@author Jasem Mutlaq
- *@version 1.2
- */
-class Align : public QWidget, public Ui::Align
-{
-
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.Ekos.Align")
-
-public:
- Align();
- ~Align();
-
- typedef enum { AZ_INIT, AZ_FIRST_TARGET, AZ_SYNCING, AZ_SLEWING, AZ_SECOND_TARGET, AZ_CORRECTING, AZ_FINISHED } AZStage;
- typedef enum { ALT_INIT, ALT_FIRST_TARGET, ALT_SYNCING, ALT_SLEWING, ALT_SECOND_TARGET, ALT_CORRECTING, ALT_FINISHED } ALTStage;
- typedef enum { GOTO_SYNC, GOTO_SLEW, GOTO_NOTHING } GotoMode;
- typedef enum { SOLVER_ONLINE, SOLVER_OFFLINE, SOLVER_REMOTE} SolverType;
-
- /** @defgroup AlignDBusInterface Ekos DBus Interface - Align Module
- * Ekos::Align interface provides advanced scripting capabilities to solve images using online or offline astrometry.net
- */
-
- /*@{*/
-
- /** DBUS interface function.
- * Select CCD
- * @param device CCD device name
- * @return Returns true if device if found and selected, false otherwise.
- */
- Q_SCRIPTABLE bool setCCD(QString device);
-
- /** DBUS interface function.
- * Start the plate-solving process given the passed image file.
- * @param filename Name of image file to solve. FITS and JPG/JPG/TIFF formats are accepted.
- * @param isGenerated Set to true if filename is generated from a CCD capture operation. If the file is loaded from any storage or network media, pass false.
- * @return Returns true if device if found and selected, false otherwise.
- */
- Q_SCRIPTABLE Q_NOREPLY void startSolving(const QString &filename, bool isGenerated=true);
-
- /** DBUS interface function.
- * Select Goto Mode of Solver. The solver mode is the action the solver performs upon successful solving.
- * @param mode 0 for Sync, 1 for SlewToTarget, 2 for Nothing
- */
- Q_SCRIPTABLE Q_NOREPLY void setGOTOMode(int mode);
-
- /** DBUS interface function.
- * Returns the solver's solution results
- * @return Returns array of doubles. First item is RA in degrees. Second item is DEC in degrees.
- */
- Q_SCRIPTABLE QList<double> getSolutionResult();
-
- /** DBUS interface function.
- * Returns the solver's current status
- * @return Returns solver status (Ekos::AlignState)
- */
- Q_SCRIPTABLE int getStatus() { return state; }
-
-#if 0
- /** DBUS interface function.
- * @return Returns true if the solver process completed or aborted, false otherwise.
- */
- Q_SCRIPTABLE bool isSolverComplete() { return m_isSolverComplete; }
-
- /** DBUS interface function.
- * @return Returns true if the solver process completed successfully, false otherwise.
- */
- Q_SCRIPTABLE bool isSolverSuccessful() { return m_isSolverSuccessful; }
-#endif
-
- /** DBUS interface function.
- * @return Returns State of load slew procedure. Idle if not started. Busy if in progress. Ok if complete. Alert if procedure failed.
- */
- Q_SCRIPTABLE int getLoadAndSlewStatus() { return loadSlewState; }
-
- /** DBUS interface function.
- * Sets the exposure of the selected CCD device.
- * @param value Exposure value in seconds
- */
- Q_SCRIPTABLE Q_NOREPLY void setExposure(double value);
-
- /** DBUS interface function.
- * Sets the arguments that gets passed to the astrometry.net offline solver.
- * @param value space-separated arguments.
- */
- Q_SCRIPTABLE Q_NOREPLY void setSolverArguments(const QString & value);
-
- /** DBUS interface function.
- * Sets the solver search area options
- * @param ra center RA for search pattern, in hours.
- * @param dec center DEC for search pattern, in degrees.
- * @param radius radius of search pattern, in degrees.
- */
- Q_SCRIPTABLE Q_NOREPLY void setSolverSearchOptions(double ra, double dec, double radius);
-
- /** DBUS interface function.
- * Sets the solver's option
- * @param useOAGT if true, use the Off-Axis Guide Telescope focal length and aperture for FOV calculations. Otherwise, the main telescope's focal length and aperture are used for the calculation.
- */
- Q_SCRIPTABLE Q_NOREPLY void setUseOAGT(bool enabled);
-
-
- /** @}*/
-
- /**
- * @brief Add CCD to the list of available CCD.
- * @param newCCD pointer to CCD device.
- */
- void addCCD(ISD::GDInterface *newCCD);
-
- /**
- * @brief Set the current telescope
- * @newTelescope pointer to telescope device.
- */
- void setTelescope(ISD::GDInterface *newTelescope);
-
- /**
- * @brief CCD information is updated, sync them.
- */
- void syncCCDInfo();
-
- /**
- * @brief Generate arguments we pass to the online and offline solvers. Keep user own arguments in place.
- */
- void generateArgs();
-
- /**
- * @brief Does our parser exist in the system?
- */
- bool isParserOK();
-
- // Log
- QString getLogText() { return logText.join("\n"); }
- void clearLog();
-
- /**
- * @brief Return FOV object used to represent the solved image orientation on the sky map.
- */
- FOV *fov();
-
-
-public slots:
-
- /**
- * @brief Process updated telescope coordinates.
- * @coord pointer to telescope coordinate property.
- */
- void processTelescopeNumber(INumberVectorProperty *coord);
-
- /**
- * @brief Check CCD and make sure information is updated and FOV is re-calculated.
- * @param CCDNum By default, we check the already selected CCD in the dropdown menu. If CCDNum is specified, the check is made against this specific CCD in the dropdown menu. CCDNum is the index of the CCD in the dropdown menu.
- */
- void checkCCD(int CCDNum=-1);
-
- /**
- * @brief checkCCDExposureProgress Track the progress of CCD exposure
- * @param targeChip Target chip under exposure
- * @param remaining how many seconds remaining
- * @param state status of exposure
- */
- void checkCCDExposureProgress(ISD::CCDChip* targetChip, double remaining, IPState state);
- /**
- * @brief Process new FITS received from CCD.
- * @param bp pointer to blob property
- */
- void newFITS(IBLOB *bp);
-
- /** \addtogroup AlignDBusInterface
- * @{
- */
-
- /** DBUS interface function.
- * Aborts the solving operation.
- */
- Q_SCRIPTABLE Q_NOREPLY void abort();
-
- /** DBUS interface function.
- * Select the solver type
- * @param type Set solver type. 0 online, 1 offline, 2 remote
- */
- Q_SCRIPTABLE Q_NOREPLY void setSolverType(int type);
-
- /** DBUS interface function.
- * Capture and solve an image using the astrometry.net engine
- * @return Returns true if the procedure started successful, false otherwise.
- */
- Q_SCRIPTABLE bool captureAndSolve();
-
- /** DBUS interface function.
- * Loads an image (FITS or JPG/TIFF) and solve its coordinates, then it slews to the solved coordinates and an image is captured and solved to ensure
- * the telescope is pointing to the same coordinates of the image.
- * @param fileURL URL to the image to solve
- */
- Q_SCRIPTABLE Q_NOREPLY void loadAndSlew(QString fileURL = QString());
-
- /** DBUS interface function.
- * Sets the binning of the selected CCD device.
- * @param binIndex Index of binning value. Default values range from 0 (binning 1x1) to 3 (binning 4x4)
- */
- Q_SCRIPTABLE Q_NOREPLY void setBinningIndex(int binIndex);
-
- /** @}*/
-
- /**
- * @brief Solver finished successfully, process the data and execute the required actions depending on the mode.
- * @param orientation Orientation of image in degrees (East of North)
- * @param ra Center RA in solved image, degrees.
- * @param dec Center DEC in solved image, degrees.
- * @param pixscale Image scale is arcsec/pixel
- */
- void solverFinished(double orientation, double ra, double dec, double pixscale);
-
- /**
- * @brief Process solver failure.
- */
- void solverFailed();
-
- /**
- * @brief We received new telescope info, process them and update FOV.
- */
- void syncTelescopeInfo();
-
- /**
- * @brief setWCSEnabled enables/disables World Coordinate System settings in the CCD driver.
- * @param enable true to enable WCS, false to disable.
- */
- void setWCSEnabled(bool enable);
-
- void setLockedFilter(ISD::GDInterface *filter, int lockedPosition);
-
- void setFocusStatus(Ekos::FocusState state);
-
- // Log
- void appendLogText(const QString &);
-
- // Capture
- void setCaptureComplete();
-
-private slots:
- /* Solver Options */
- void checkLineEdits();
- void copyCoordsToBoxes();
- void clearCoordBoxes();
-
- /* Polar Alignment */
- void checkPolarAlignment();
- void measureAltError();
- void measureAzError();
- void correctAzError();
- void correctAltError();
-
- void processFilterNumber(INumberVectorProperty *nvp);
-
- void setDefaultCCD(QString ccd);
-
- void saveSettleTime();
-
-signals:
- void newLog();
- void solverComplete(bool);
- void solverSlewComplete();
- void newStatus(Ekos::AlignState state);
- void newSolutionDeviation(double ra_arcsecs, double de_arcsecs);
-
-private:
- /**
- * @brief Calculate Field of View of CCD+Telescope combination that we need to pass to astrometry.net solver.
- */
- void calculateFOV();
-
- /**
- * @brief After a solver process is completed successfully, execute the mode as set by the user (GOTO or Polar Alignment)
- */
- void executeMode();
-
- /**
- * @brief After a solver process is completed successfully, sync, slew to target, or do nothing as set by the user.
- */
- void executeGOTO();
-
- /**
- * @brief After a solver process is completed successfully, measure Azimuth or Altitude error as requested by the user.
- */
- void executePolarAlign();
-
- /**
- * @brief Sync the telescope to the solved alignment coordinate.
- */
- void Sync();
-
- /**
- * @brief Sync the telescope to the solved alignment coordinate, and then slew to the target coordinate.
- */
- void SlewToTarget();
-
- /**
- * @brief Calculate polar alignment error magnitude and direction.
- * The calculation is performed by first capturing and solving a frame, then slewing 30 arcminutes and solving another frame to find the exact coordinates, then computing the error.
- * @param initRA RA of first frame.
- * @param initDEC DEC of first frame
- * @param finalRA RA of second frame
- * @param finalDEC DEC of second frame
- * @param initAz Azimuth of first frame
- */
- void calculatePolarError(double initRA, double initDEC, double finalRA, double finalDEC, double initAz);
-
- /**
- * @brief Get formatted RA & DEC coordinates compatible with astrometry.net format.
- * @param ra Right ascension
- * @param dec Declination
- * @param ra_str will contain the formatted RA string
- * @param dec_str will contain the formatted DEC string
- */
- void getFormattedCoords(double ra, double dec, QString &ra_str, QString &dec_str);
-
- /**
- * @brief getSolverOptionsFromFITS Generates a set of solver options given the supplied FITS image. The function reads FITS keyword headers and build the argument list accordingly. In case of a missing header keyword, it falls back to
- * the Alignment module existing values.
- * @param filename FITS path
- * @return List of Solver options
- */
- QStringList getSolverOptionsFromFITS(const QString &filename);
-
- // Which chip should we invoke in the current CCD?
- bool useGuideHead;
- // Can the mount sync its coordinates to those set by Ekos?
- bool canSync;
- // LoadSlew mode is when we load an image and solve it, no capture is done.
- //bool loadSlewMode;
- // If load and slew is solved successfully, coordinates obtained, slewed to target, and then captured, solved, and re-slewed to target again.
- IPState loadSlewState;
- // Solver iterations count
- uint8_t solverIterations;
-
- // Keep track of solver status
- //bool m_isSolverComplete;
- //bool m_isSolverSuccessful;
- //bool m_slewToTargetSelected;
-
- // Focus
- //bool isFocusBusy;
-
- // FOV
- double ccd_hor_pixel, ccd_ver_pixel, focal_length, aperture, fov_x, fov_y;
- int ccd_width, ccd_height;
-
- // Keep track of solver results
- double sOrientation, sRA, sDEC;
-
- // Solver alignment coordinates
- SkyPoint alignCoord;
- // Target coordinates we need to slew to
- SkyPoint targetCoord;
- // Actual current telescope coordinates
- SkyPoint telescopeCoord;
- // Coord from Load & Slew
- SkyPoint loadSlewCoord;
- // Difference between solution and target coordinate
- double targetDiff;
-
- // Progress icon if the solver is running
- QProgressIndicator *pi;
-
- // Keep track of how long the solver is running
- QTime solverTimer;
-
- // Polar Alignment
- AZStage azStage;
- ALTStage altStage;
- double azDeviation, altDeviation;
- double decDeviation;
- static const double RAMotion;
- static const float SIDRATE;
-
- // Online and Offline parsers
- AstrometryParser *parser;
- OnlineAstrometryParser *onlineParser;
- OfflineAstrometryParser *offlineParser;
- RemoteAstrometryParser *remoteParser;
-
- // Pointers to our devices
- ISD::Telescope *currentTelescope;
- ISD::CCD *currentCCD;
- QList<ISD::CCD *> CCDs;
-
- // Optional device filter
- ISD::GDInterface *currentFilter;
- int lockedFilterIndex;
- int currentFilterIndex;
- // True if we need to change filter position and wait for result before continuing capture
- bool filterPositionPending;
-
- // Keep track of solver FOV to be plotted in the skymap after each successful solve operation
- FOV *solverFOV;
-
- // WCS
- bool m_wcsSynced;
-
- // Log
- QStringList logText;
-
- // Capture retries
- int retries;
-
- // State
- AlignState state;
- FocusState focusState;
-
- // Track which upload mode the CCD is set to. If set to UPLOAD_LOCAL, then we need to switch it to UPLOAD_CLIENT in order to do focusing, and then switch it back to UPLOAD_LOCAL
- ISD::CCD::UploadMode rememberUploadMode;
-
- GotoMode currentGotoMode;
-
- QString dirPath;
-};
-
-}
-
-#endif // ALIGN_H
diff --git a/kstars/ekos/align.ui b/kstars/ekos/align.ui
deleted file mode 100644
index 5e3e50f..0000000
--- a/kstars/ekos/align.ui
+++ /dev/null
@@ -1,973 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>Align</class>
- <widget class="QWidget" name="Align">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>693</width>
- <height>286</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_5">
- <property name="spacing">
- <number>1</number>
- </property>
- <property name="leftMargin">
- <number>3</number>
- </property>
- <property name="topMargin">
- <number>3</number>
- </property>
- <property name="rightMargin">
- <number>3</number>
- </property>
- <property name="bottomMargin">
- <number>3</number>
- </property>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_7">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <layout class="QVBoxLayout" name="verticalLayout_3">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <widget class="QGroupBox" name="controlBox">
- <property name="title">
- <string>Plate Solver Control</string>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout_5">
- <property name="leftMargin">
- <number>3</number>
- </property>
- <property name="topMargin">
- <number>3</number>
- </property>
- <property name="rightMargin">
- <number>3</number>
- </property>
- <property name="bottomMargin">
- <number>3</number>
- </property>
- <item>
- <layout class="QGridLayout" name="controlLayout">
- <property name="spacing">
- <number>1</number>
- </property>
- <item row="0" column="1">
- <widget class="QPushButton" name="solveB">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="text">
- <string>Capture &amp;&amp; Solve</string>
- </property>
- </widget>
- </item>
- <item row="0" column="3">
- <widget class="QPushButton" name="stopB">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Stop</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>Mode:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout_10">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <widget class="QRadioButton" name="gotoR">
- <property name="toolTip">
- <string>Solve the image and sync/slew the mount accordingly</string>
- </property>
- <property name="statusTip">
- <string/>
- </property>
- <property name="text">
- <string>&amp;GOTO</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Control:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QPushButton" name="loadSlewB">
- <property name="toolTip">
- <string>Load a FITS image and solve. Slew mount to image central coordinates.</string>
- </property>
- <property name="text">
- <string>Load &amp;&amp; Slew...</string>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QRadioButton" name="polarR">
- <property name="toolTip">
- <string>Measure polar alignment deviations in azimuth and altitude axis</string>
- </property>
- <property name="statusTip">
- <string/>
- </property>
- <property name="text">
- <string>Polar Alignment</string>
- </property>
- <property name="checked">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>47</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="gotoBox">
- <property name="toolTip">
- <string>Select which action to perform after the captured image is solved</string>
- </property>
- <property name="statusTip">
- <string>Select what action to take once a solution is found.</string>
- </property>
- <property name="title">
- <string>GOTO Mode</string>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout_3">
- <property name="spacing">
- <number>1</number>
- </property>
- <property name="leftMargin">
- <number>3</number>
- </property>
- <property name="topMargin">
- <number>3</number>
- </property>
- <property name="rightMargin">
- <number>3</number>
- </property>
- <property name="bottomMargin">
- <number>3</number>
- </property>
- <item>
- <widget class="QRadioButton" name="syncR">
- <property name="toolTip">
- <string>Synchronize the telescope to the solution coordinates</string>
- </property>
- <property name="statusTip">
- <string/>
- </property>
- <property name="text">
- <string>S&amp;ync</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">gotoModeButtonGroup</string>
- </attribute>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="slewR">
- <property name="toolTip">
- <string>Synchronize the telescope to the solution coordinates and then slew to the target coordinates</string>
- </property>
- <property name="statusTip">
- <string/>
- </property>
- <property name="text">
- <string>S&amp;lew to Target</string>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">gotoModeButtonGroup</string>
- </attribute>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="nothingR">
- <property name="toolTip">
- <string>Just solve</string>
- </property>
- <property name="statusTip">
- <string/>
- </property>
- <property name="text">
- <string>&amp;Nothing</string>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">gotoModeButtonGroup</string>
- </attribute>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer_6">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>13</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_2">
- <property name="title">
- <string>Plate Solver Options</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <property name="spacing">
- <number>1</number>
- </property>
- <property name="leftMargin">
- <number>3</number>
- </property>
- <property name="topMargin">
- <number>3</number>
- </property>
- <property name="rightMargin">
- <number>3</number>
- </property>
- <property name="bottomMargin">
- <number>3</number>
- </property>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <layout class="QGridLayout" name="gridLayout_4">
- <property name="spacing">
- <number>1</number>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="textLabel1_6">
- <property name="toolTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>CCD:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QComboBox" name="CCDCaptureCombo"/>
- </item>
- <item row="0" column="2">
- <widget class="QLabel" name="label_7">
- <property name="toolTip">
- <string/>
- </property>
- <property name="text">
- <string>Exp:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="3">
- <widget class="QDoubleSpinBox" name="exposureIN">
- <property name="toolTip">
- <string>Exposure duration in seconds</string>
- </property>
- <property name="minimum">
- <double>0.100000000000000</double>
- </property>
- <property name="maximum">
- <double>60.000000000000000</double>
- </property>
- <property name="singleStep">
- <double>0.500000000000000</double>
- </property>
- <property name="value">
- <double>3.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="0" column="4">
- <widget class="QLabel" name="label_18">
- <property name="toolTip">
- <string/>
- </property>
- <property name="text">
- <string>Bin:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="5">
- <widget class="QComboBox" name="binningCombo">
- <property name="toolTip">
- <string>Camera binning</string>
- </property>
- </widget>
- </item>
- <item row="0" column="6" colspan="2">
- <widget class="QCheckBox" name="alignDarkFrameCheck">
- <property name="toolTip">
- <string>Subtract dark frame. If no suitable dark frame is available, a dark frame shall be captured.</string>
- </property>
- <property name="text">
- <string>Dark</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_15">
- <property name="toolTip">
- <string>estimated RA of target center to limit the solver's search area</string>
- </property>
- <property name="text">
- <string>RA:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="dmsBox" name="raBox">
- <property name="toolTip">
- <string/>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QLabel" name="label_16">
- <property name="toolTip">
- <string>estimated DEC of target center to limit the solver's search area</string>
- </property>
- <property name="text">
- <string>Dec:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="3">
- <widget class="dmsBox" name="decBox">
- <property name="toolTip">
- <string/>
- </property>
- </widget>
- </item>
- <item row="1" column="4">
- <widget class="QLabel" name="label_17">
- <property name="text">
- <string>Radius:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="5">
- <widget class="QLineEdit" name="radiusBox">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip">
- <string>The solver's search radius in degrees round the estimated RA and DEC</string>
- </property>
- <property name="statusTip">
- <string/>
- </property>
- <property name="text">
- <string>30</string>
- </property>
- </widget>
- </item>
- <item row="1" column="6">
- <widget class="QPushButton" name="syncBoxesB">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>22</width>
- <height>22</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>22</width>
- <height>22</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Fill RA &amp;amp; DEC values from telescope coordinates and update options</string>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="iconSize">
- <size>
- <width>22</width>
- <height>22</height>
- </size>
- </property>
- </widget>
- </item>
- <item row="1" column="7">
- <widget class="QPushButton" name="clearBoxesB">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>22</width>
- <height>22</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>22</width>
- <height>22</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Clear RA &amp; DEC values and reset solver options</string>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="iconSize">
- <size>
- <width>22</width>
- <height>22</height>
- </size>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="horizontalSpacer_3">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_11">
- <item>
- <widget class="QLabel" name="label_14">
- <property name="text">
- <string>Options:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="solverOptions">
- <property name="statusTip">
- <string>Additional options to be the solver</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_12">
- <item>
- <widget class="QLabel" name="label_21">
- <property name="text">
- <string>Solver:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="onlineSolverR">
- <property name="toolTip">
- <string>Use online astrometry.net solver to solve the image. You must have an internet connection and a valid API key.</string>
- </property>
- <property name="text">
- <string>Online</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">solverTypeGroup</string>
- </attribute>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="offlineSolverR">
- <property name="toolTip">
- <string>Use offline astrometry.net solver. You must install all the necessary index files for your field of view.</string>
- </property>
- <property name="text">
- <string>Offline</string>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">solverTypeGroup</string>
- </attribute>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="remoteSolverR">
- <property name="toolTip">
- <string>Use astrometry solver on remote machine running INDI server.</string>
- </property>
- <property name="text">
- <string>Remote</string>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">solverTypeGroup</string>
- </attribute>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="verticalSpacer_7">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>7</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- <zorder>verticalSpacer_7</zorder>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="Line" name="line">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_6">
- <item>
- <widget class="QGroupBox" name="groupBox_4">
- <property name="title">
- <string>Solution Coordinates</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0">
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>RA:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_8">
- <property name="text">
- <string>FOV:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="label_10">
- <property name="text">
- <string>Rot:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QCheckBox" name="kcfg_solverOTA">
- <property name="toolTip">
- <string>Use Off-Axis Guide Telescope for FOV calculations</string>
- </property>
- <property name="text">
- <string>OAGT</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_6">
- <property name="text">
- <string>DEC:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLineEdit" name="SolverDecOut">
- <property name="readOnly">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLineEdit" name="SolverRAOut">
- <property name="readOnly">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLineEdit" name="FOVOut">
- <property name="text">
- <string/>
- </property>
- <property name="readOnly">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="3" column="2">
- <widget class="QLabel" name="label_11">
- <property name="toolTip">
- <string>East of North</string>
- </property>
- <property name="text">
- <string comment="East of North">E of N</string>
- </property>
- </widget>
- </item>
- <item row="4" column="1">
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="3" column="1">
- <widget class="QLineEdit" name="RotOut">
- <property name="readOnly">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_5">
- <property name="title">
- <string>Telescope Coordinates</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_4">
- <item>
- <layout class="QGridLayout" name="gridLayout_3">
- <item row="0" column="0">
- <widget class="QLabel" name="label_12">
- <property name="text">
- <string>RA:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLineEdit" name="ScopeRAOut">
- <property name="readOnly">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_13">
- <property name="text">
- <string>DEC:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLineEdit" name="ScopeDecOut">
- <property name="readOnly">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_9">
- <property name="text">
- <string>Accuracy</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <item>
- <widget class="QSpinBox" name="accuracySpin">
- <property name="toolTip">
- <string>Accuracy threshold in arcseconds between solution and target coordinates. Plate solver shall be repeatedly executed until the solution coordinates are below the accuracy threshold</string>
- </property>
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>300</number>
- </property>
- <property name="singleStep">
- <number>10</number>
- </property>
- <property name="value">
- <number>30</number>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_20">
- <property name="text">
- <string>arcsec</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="label_22">
- <property name="toolTip">
- <string>After telescope complete slewing, wait until it settles before capturing the next image.</string>
- </property>
- <property name="text">
- <string>Settle</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout_4">
- <item>
- <widget class="QSpinBox" name="delaySpin">
- <property name="toolTip">
- <string>After telescope completes slewing, delay capture of next image</string>
- </property>
- <property name="maximum">
- <number>5000</number>
- </property>
- <property name="singleStep">
- <number>100</number>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_23">
- <property name="toolTip">
- <string>Milliseconds</string>
- </property>
- <property name="text">
- <string>ms</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="verticalSpacer_2">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>0</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="alignmentBox">
- <property name="title">
- <string>Polar Alignment Mode</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>Az Error:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLineEdit" name="azError">
- <property name="readOnly">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QPushButton" name="measureAzB">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Measure Az Error</string>
- </property>
- </widget>
- </item>
- <item row="0" column="3">
- <widget class="QPushButton" name="correctAzB">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Correct Az Error</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_4">
- <property name="text">
- <string>Alt Error:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLineEdit" name="altError">
- <property name="readOnly">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QPushButton" name="measureAltB">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Measure Alt Error</string>
- </property>
- </widget>
- </item>
- <item row="1" column="3">
- <widget class="QPushButton" name="correctAltB">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Correct Alt Error</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="verticalSpacer_3">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>52</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="verticalSpacer_4">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>dmsBox</class>
- <extends>QLineEdit</extends>
- <header>widgets/dmsbox.h</header>
- <container>1</container>
- </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
- <buttongroups>
- <buttongroup name="solverTypeGroup"/>
- <buttongroup name="gotoModeButtonGroup"/>
- </buttongroups>
-</ui>
diff --git a/kstars/ekos/astrometryparser.h b/kstars/ekos/astrometryparser.h
deleted file mode 100644
index 14e5b85..0000000
--- a/kstars/ekos/astrometryparser.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Astrometry.net Parser
- Copyright (C) 2012 Jasem Mutlaq <mutlaqja@ikarustech.com>
-
- This application is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-*/
-
-#ifndef ASTROMETRYPARSER_H
-#define ASTROMETRYPARSER_H
-
-#include <QObject>
-
-namespace Ekos
-{
-
-class Align;
-
-/**
- * @class AstrometryParser
- * AstrometryParser is an interface for online and offline astrometry parsers.
- *
- * @authro Jasem Mutlaq
- */
-
-class AstrometryParser : public QObject
-{
- Q_OBJECT
-
-public:
- AstrometryParser();
- virtual ~AstrometryParser();
-
- virtual void setAlign(Align *align) = 0;
- virtual bool init() = 0;
- virtual void verifyIndexFiles(double fov_x, double fov_y) =0;
- virtual bool startSovler(const QString &filename, const QStringList &args, bool generated=true) =0;
- virtual bool stopSolver() = 0;
-
-signals:
- void solverFinished(double orientation, double ra, double dec, double pixscale);
- void solverFailed();
-};
-
-}
-
-#endif // ASTROMETRYPARSER_H
diff --git a/kstars/ekos/calibrationoptions.ui b/kstars/ekos/calibrationoptions.ui
deleted file mode 100644
index d7411a2..0000000
--- a/kstars/ekos/calibrationoptions.ui
+++ /dev/null
@@ -1,277 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>calibrationOptions</class>
- <widget class="QDialog" name="calibrationOptions">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>475</width>
- <height>241</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>Calibration Options</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_3">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_3">
- <item>
- <widget class="QGroupBox" name="groupBox">
- <property name="toolTip">
- <string>Specify the source the flat field evenly illuminated light source</string>
- </property>
- <property name="title">
- <string>Flat Source</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QRadioButton" name="manualSourceC">
- <property name="toolTip">
- <string>Light source triggered by the user manually</string>
- </property>
- <property name="text">
- <string>Manual</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="flatDeviceSourceC">
- <property name="toolTip">
- <string>For dark and bias frames, close the dust cap before proceeding. For flat frames, close the dust cap and turn on the light source.</string>
- </property>
- <property name="text">
- <string>Dust Cover with Built-in Flat Light</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="darkDeviceSourceC">
- <property name="toolTip">
- <string>For dark and bias frames, close the dust cap before proceeding. For flat frames, open the dust cap and turn on the light source.</string>
- </property>
- <property name="text">
- <string>Dust Cover with External Flat Light</string>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QRadioButton" name="wallSourceC">
- <property name="toolTip">
- <string>Slew mount to the specified Azimuth/Altitude coordinates before taking flat field images</string>
- </property>
- <property name="text">
- <string>Wall</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Az:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="dmsBox" name="azBox">
- <property name="toolTip">
- <string/>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>Alt:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="dmsBox" name="altBox">
- <property name="toolTip">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QRadioButton" name="dawnDuskFlatsC">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="toolTip">
- <string>Use Dawn and Dusk light</string>
- </property>
- <property name="text">
- <string>Dawn/Dusk</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer_2">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_2">
- <property name="title">
- <string>Flat Duration</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <widget class="QRadioButton" name="manualDurationC">
- <property name="toolTip">
- <string>Use the frame exposure value</string>
- </property>
- <property name="text">
- <string>Manual</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <item>
- <widget class="QRadioButton" name="ADUC">
- <property name="toolTip">
- <string>Calculate optimal exposure time given the required ADU. If a controllable device is selected, calculate optimal brightness.</string>
- </property>
- <property name="text">
- <string>ADU</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="ADUValue">
- <property name="toolTip">
- <string/>
- </property>
- <property name="maximum">
- <number>65535</number>
- </property>
- <property name="singleStep">
- <number>1000</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QCheckBox" name="parkMountC">
- <property name="text">
- <string>Park Mount</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="parkDomeC">
- <property name="text">
- <string>Park Dome</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>dmsBox</class>
- <extends>QLineEdit</extends>
- <header>widgets/dmsbox.h</header>
- <container>1</container>
- </customwidget>
- </customwidgets>
- <tabstops>
- <tabstop>manualSourceC</tabstop>
- <tabstop>flatDeviceSourceC</tabstop>
- <tabstop>darkDeviceSourceC</tabstop>
- <tabstop>wallSourceC</tabstop>
- <tabstop>azBox</tabstop>
- <tabstop>altBox</tabstop>
- <tabstop>dawnDuskFlatsC</tabstop>
- <tabstop>manualDurationC</tabstop>
- <tabstop>ADUC</tabstop>
- <tabstop>ADUValue</tabstop>
- </tabstops>
- <resources/>
- <connections>
- <connection>
- <sender>buttonBox</sender>
- <signal>accepted()</signal>
- <receiver>calibrationOptions</receiver>
- <slot>accept()</slot>
- <hints>
- <hint type="sourcelabel">
- <x>248</x>
- <y>254</y>
- </hint>
- <hint type="destinationlabel">
- <x>157</x>
- <y>274</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>buttonBox</sender>
- <signal>rejected()</signal>
- <receiver>calibrationOptions</receiver>
- <slot>reject()</slot>
- <hints>
- <hint type="sourcelabel">
- <x>316</x>
- <y>260</y>
- </hint>
- <hint type="destinationlabel">
- <x>286</x>
- <y>274</y>
- </hint>
- </hints>
- </connection>
- </connections>
-</ui>
diff --git a/kstars/ekos/capture.cpp b/kstars/ekos/capture.cpp
deleted file mode 100644
index 0f7b1aa..0000000
--- a/kstars/ekos/capture.cpp
+++ /dev/null
@@ -1,3805 +0,0 @@
-/* Ekos
- Copyright (C) 2012 Jasem Mutlaq <mutlaqja@ikarustech.com>
-
- This application is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
- */
-
-#include <QFileDialog>
-#include <QDirIterator>
-#include <QStandardPaths>
-
-#include <KMessageBox>
-#include <KDirWatch>
-#include <KLocalizedString>
-#include <KNotifications/KNotification>
-
-#include <basedevice.h>
-#include <lilxml.h>
-
-#include "Options.h"
-
-#include "kstars.h"
-#include "kstarsdata.h"
-
-#include "capture.h"
-#include "sequencejob.h"
-
-#include "indi/driverinfo.h"
-#include "indi/indifilter.h"
-#include "indi/clientmanager.h"
-
-#include "fitsviewer/fitsviewer.h"
-#include "fitsviewer/fitsview.h"
-
-#include "darklibrary.h"
-#include "ekosmanager.h"
-#include "captureadaptor.h"
-#include "ui_calibrationoptions.h"
-
-#include "QProgressIndicator.h"
-
-#define INVALID_TEMPERATURE 10000
-#define INVALID_HA 10000
-#define MF_TIMER_TIMEOUT 90000
-#define MF_RA_DIFF_LIMIT 4
-#define MAX_CAPTURE_RETRIES 3
-
-namespace Ekos
-{
-
-Capture::Capture()
-{
- setupUi(this);
-
- new CaptureAdaptor(this);
- QDBusConnection::sessionBus().registerObject("/KStars/Ekos/Capture", this);
-
- dirPath = QUrl(QDir::homePath());
-
- state = CAPTURE_IDLE;
- focusState = FOCUS_IDLE;
- guideState = GUIDE_IDLE;
- alignState = ALIGN_IDLE;
-
- currentCCD = NULL;
- currentTelescope = NULL;
- currentFilter = NULL;
- dustCap = NULL;
- lightBox= NULL;
- dome = NULL;
-
- filterSlot = NULL;
- filterName = NULL;
- activeJob = NULL;
-
- targetChip = NULL;
- guideChip = NULL;
-
- targetADU = 0;
- flatFieldDuration = DURATION_MANUAL;
- flatFieldSource = SOURCE_MANUAL;
- calibrationStage = CAL_NONE;
- preMountPark = false;
- preDomePark = false;
-
- deviationDetected = false;
- spikeDetected = false;
- isBusy = false;
-
- ignoreJobProgress=true;
-
- dustCapLightEnabled = lightBoxLightEnabled = false;
-
- //isAutoGuiding = false;
- guideDither = false;
- isAutoFocus = false;
- autoFocusStatus = false;
- resumeAlignmentAfterFlip= false;
-
- mDirty = false;
- jobUnderEdit = false;
- currentFilterPosition = -1;
-
- //calibrationState = CALIBRATE_NONE;
- meridianFlipStage = MF_NONE;
- resumeGuidingAfterFlip = false;
-
- //ADURaw1 = ADURaw2 = ExpRaw1 = ExpRaw2 = -1;
- //ADUSlope = 0;
-
- pi = new QProgressIndicator(this);
-
- progressLayout->addWidget(pi, 0, 4, 1, 1);
-
- seqFileCount = 0;
- //seqWatcher = new KDirWatch();
- seqTimer = new QTimer(this);
- connect(seqTimer, SIGNAL(timeout()), this, SLOT(captureImage()));
-
- connect(startB, SIGNAL(clicked()), this, SLOT(toggleSequence()));
- connect(pauseB, SIGNAL(clicked()), this, SLOT(pause()));
-
- startB->setIcon(QIcon::fromTheme("media-playback-start"));
- pauseB->setIcon(QIcon::fromTheme("media-playback-pause"));
-
- connect(binXIN, SIGNAL(valueChanged(int)), binYIN, SLOT(setValue(int)));
-
- connect(CCDCaptureCombo, SIGNAL(activated(QString)), this, SLOT(setDefaultCCD(QString)));
- connect(CCDCaptureCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(checkCCD(int)));
-
-
- connect(FilterCaptureCombo, SIGNAL(activated(int)), this, SLOT(checkFilter(int)));
-
- connect(previewB, SIGNAL(clicked()), this, SLOT(captureOne()));
-
- //connect( seqWatcher, SIGNAL(dirty(QString)), this, SLOT(checkSeqFile(QString)));
-
- connect(addToQueueB, SIGNAL(clicked()), this, SLOT(addJob()));
- connect(removeFromQueueB, SIGNAL(clicked()), this, SLOT(removeJob()));
- connect(queueUpB, SIGNAL(clicked()), this, SLOT(moveJobUp()));
- connect(queueDownB, SIGNAL(clicked()), this, SLOT(moveJobDown()));
- connect(selectFITSDirB, SIGNAL(clicked()), this, SLOT(saveFITSDirectory()));
- connect(queueSaveB, SIGNAL(clicked()), this, SLOT(saveSequenceQueue()));
- connect(queueSaveAsB, SIGNAL(clicked()), this, SLOT(saveSequenceQueueAs()));
- connect(queueLoadB, SIGNAL(clicked()), this, SLOT(loadSequenceQueue()));
- connect(resetB, SIGNAL(clicked()), this, SLOT(resetJobs()));
- connect(queueTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(editJob(QModelIndex)));
- connect(queueTable, SIGNAL(itemSelectionChanged()), this, SLOT(resetJobEdit()));
- connect(setTemperatureB, SIGNAL(clicked()), this, SLOT(setTemperature()));
- connect(temperatureIN, SIGNAL(editingFinished()), setTemperatureB, SLOT(setFocus()));
- connect(frameTypeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(checkFrameType(int)));
- connect(resetFrameB, SIGNAL(clicked()), this, SLOT(resetFrame()));
- connect(calibrationB, SIGNAL(clicked()), this, SLOT(openCalibrationDialog()));
-
- addToQueueB->setIcon(QIcon::fromTheme("list-add"));
- removeFromQueueB->setIcon(QIcon::fromTheme("list-remove"));
- queueUpB->setIcon(QIcon::fromTheme("go-up"));
- queueDownB->setIcon(QIcon::fromTheme("go-down"));
- selectFITSDirB->setIcon(QIcon::fromTheme("document-open-folder"));
- queueLoadB->setIcon(QIcon::fromTheme("document-open"));
- queueSaveB->setIcon(QIcon::fromTheme("document-save"));
- queueSaveAsB->setIcon(QIcon::fromTheme("document-save-as"));
- resetB->setIcon(QIcon::fromTheme("system-reboot"));
- resetFrameB->setIcon(QIcon::fromTheme("view-refresh"));
- calibrationB->setIcon(QIcon::fromTheme("run-build"));
-
- addToQueueB->setToolTip(i18n("Add job to sequence queue"));
- removeFromQueueB->setToolTip(i18n("Remove job from sequence queue"));
-
- fitsDir->setText(Options::fitsDir());
-
- seqExpose = 0;
- seqTotalCount = 0;
- seqCurrentCount = 0;
- seqDelay = 0;
- fileHFR=0;
- useGuideHead = false;
- guideDither = false;
- firstAutoFocus = true;
-
- foreach(QString filter, FITSViewer::filterTypes)
- filterCombo->addItem(filter);
-
- guideDeviationCheck->setChecked(Options::enforceGuideDeviation());
- guideDeviation->setValue(Options::guideDeviation());
- autofocusCheck->setChecked(Options::enforceAutofocus());
- parkCheck->setChecked(Options::autoParkTelescope());
- meridianCheck->setChecked(Options::autoMeridianFlip());
- meridianHours->setValue(Options::autoMeridianHours());
-
- connect(autofocusCheck, SIGNAL(toggled(bool)), this, SLOT(setDirty()));
- connect(HFRPixels, SIGNAL(valueChanged(double)), this, SLOT(setDirty()));
- connect(guideDeviationCheck, SIGNAL(toggled(bool)), this, SLOT(setDirty()));
- connect(guideDeviation, SIGNAL(valueChanged(double)), this, SLOT(setDirty()));
- connect(meridianCheck, SIGNAL(toggled(bool)), this, SLOT(setDirty()));
- connect(meridianHours, SIGNAL(valueChanged(double)), this, SLOT(setDirty()));
- connect(parkCheck, SIGNAL(toggled(bool)), this, SLOT(setDirty()));
-
-
- // FIXME remove this later
- connect(&postCaptureScript, SIGNAL(finished(int)), this, SLOT(postScriptFinished(int)));
-}
-
-Capture::~Capture()
-{
- qDeleteAll(jobs);
-}
-
-void Capture::setDefaultCCD(QString ccd)
-{
- Options::setDefaultCaptureCCD(ccd);
-}
-
-void Capture::addCCD(ISD::GDInterface *newCCD)
-{
- ISD::CCD *ccd = static_cast<ISD::CCD *> (newCCD);
-
- if (CCDs.contains(ccd))
- return;
-
- CCDs.append(ccd);
-
- CCDCaptureCombo->addItem(ccd->getDeviceName());
-
- if (Filters.count() > 0)
- syncFilterInfo();
- //checkCCD(CCDs.count()-1);
- //CCDCaptureCombo->setCurrentIndex(CCDs.count()-1);
-
-}
-
-void Capture::addGuideHead(ISD::GDInterface *newCCD)
-{
- QString guiderName = newCCD->getDeviceName() + QString(" Guider");
-
- if (CCDCaptureCombo->findText(guiderName) == -1)
- {
- CCDCaptureCombo->addItem(guiderName);
- CCDs.append(static_cast<ISD::CCD *> (newCCD));
- }
-}
-
-void Capture::addFilter(ISD::GDInterface *newFilter)
-{
- foreach(ISD::GDInterface *filter, Filters)
- {
- if (!strcmp(filter->getDeviceName(), newFilter->getDeviceName()))
- return;
- }
-
- FilterCaptureCombo->addItem(newFilter->getDeviceName());
-
- Filters.append(static_cast<ISD::Filter *>(newFilter));
-
- checkFilter(0);
-
- FilterCaptureCombo->setCurrentIndex(0);
-
-}
-
-void Capture::pause()
-{
- pauseFunction=NULL;
- state = CAPTURE_PAUSED;
- emit newStatus(Ekos::CAPTURE_PAUSED);
- appendLogText(i18n("Sequence shall be paused after current exposure is complete."));
- pauseB->setEnabled(false);
-
- startB->setIcon(QIcon::fromTheme("media-playback-start"));
- startB->setToolTip(i18n("Resume Sequence"));
-}
-
-void Capture::toggleSequence()
-{
- if (state == CAPTURE_PAUSED)
- {
- startB->setIcon(QIcon::fromTheme("media-playback-stop"));
- startB->setToolTip(i18n("Stop Sequence"));
- pauseB->setEnabled(true);
-
- state = CAPTURE_CAPTURING;
- emit newStatus(Ekos::CAPTURE_CAPTURING);
-
- appendLogText(i18n("Sequence resumed."));
-
- // Call from where ever we have left of when we paused
- if (pauseFunction)
- (this->*pauseFunction)();
- }
- else if (state == CAPTURE_IDLE || state == CAPTURE_COMPLETE)
- {
- start();
- }
- else
- {
- abort();
- }
-}
-
-void Capture::start()
-{
- if (darkSubCheck->isChecked())
- {
- KMessageBox::error(this, i18n("Auto dark subtract is not supported in batch mode."));
- return;
- }
-
- Options::setGuideDeviation(guideDeviation->value());
- Options::setEnforceGuideDeviation(guideDeviationCheck->isChecked());
- Options::setEnforceAutofocus(autofocusCheck->isChecked());
- Options::setAutoMeridianFlip(meridianCheck->isChecked());
- Options::setAutoMeridianHours(meridianHours->value());
- Options::setAutoParkTelescope(parkCheck->isChecked());
-
- if (queueTable->rowCount() ==0)
- addJob();
-
- SequenceJob *first_job = NULL;
-
- foreach(SequenceJob *job, jobs)
- {
- if (job->getStatus() == SequenceJob::JOB_IDLE || job->getStatus() == SequenceJob::JOB_ABORTED)
- {
- first_job = job;
- break;
- }
- }
-
- if (first_job == NULL)
- {
- foreach(SequenceJob *job, jobs)
- {
- if (job->getStatus() != SequenceJob::JOB_DONE)
- {
- appendLogText(i18n("No pending jobs found. Please add a job to the sequence queue."));
- return;
- }
- }
-
- if (KMessageBox::warningContinueCancel(NULL, i18n("All jobs are complete. Do you want to reset the status of all jobs and restart capturing?"),
- i18n("Reset job status"), KStandardGuiItem::cont(), KStandardGuiItem::cancel(),
- "reset_job_complete_status_warning") !=KMessageBox::Continue)
- return;
-
- foreach(SequenceJob *job, jobs)
- job->resetStatus();
-
- first_job = jobs.first();
- }
-
- deviationDetected = false;
- spikeDetected = false;
-
- initialHA = getCurrentHA();
- meridianFlipStage = MF_NONE;
-
- // Check if we need to update the sequence directory numbers before starting
- /*for (int i=0; i < jobs.count(); i++)
- {
- QString firstDir = jobs.at(i)->getFITSDir();
- int sequenceID=1;
-
- for (int j=i+1; j < jobs.count(); j++)
- {
- if (firstDir == jobs.at(j)->getFITSDir())
- {
- jobs.at(i)->setFITSDir(QString("%1/Sequence_1").arg(firstDir));
- jobs.at(j)->setFITSDir(QString("%1/Sequence_%2").arg(jobs.at(j)->getFITSDir()).arg(++sequenceID));
- }
- }
- }*/
-
- state = CAPTURE_PROGRESS;
- emit newStatus(Ekos::CAPTURE_PROGRESS);
-
- startB->setIcon(QIcon::fromTheme("media-playback-stop"));
- startB->setToolTip(i18n("Stop Sequence"));
- pauseB->setEnabled(true);
-
- foreach (QAbstractButton *button, queueEditButtonGroup->buttons())
- button->setEnabled(false);
-
- prepareJob(first_job);
-
-}
-
-void Capture::stop(bool abort)
-{
-
- retries = 0;
- seqTotalCount = 0;
- seqCurrentCount = 0;
- //ADURaw1 = ADURaw2 = ExpRaw1 = ExpRaw2 = -1;
- //ADUSlope = 0;
- ADURaw.clear();
- ExpRaw.clear();
-
- calibrationStage = CAL_NONE;
-
- if (activeJob)
- {
- if (activeJob->getStatus() == SequenceJob::JOB_BUSY)
- {
- KNotification::event( QLatin1String( "CaptureFailed"), i18n("CCD capture failed with errors") );
- activeJob->abort();
- emit newStatus(Ekos::CAPTURE_ABORTED);
- }
-
- activeJob->disconnect(this);
- activeJob->reset();
- }
-
- state = CAPTURE_IDLE;
-
- // Turn off any calibration light, IF they were turned on by Capture module
- if (dustCap && dustCapLightEnabled)
- {
- dustCapLightEnabled = false;
- dustCap->SetLightEnabled(false);
- }
- if (lightBox && lightBoxLightEnabled)
- {
- lightBoxLightEnabled = false;
- lightBox->SetLightEnabled(false);
- }
-
- secondsLabel->clear();
- disconnect(currentCCD, SIGNAL(BLOBUpdated(IBLOB*)), this, SLOT(newFITS(IBLOB*)));
- disconnect(currentCCD, SIGNAL(newImage(QImage*,ISD::CCDChip*)), this, SLOT(sendNewImage(QImage*,ISD::CCDChip*)));
- disconnect(currentCCD, SIGNAL(newExposureValue(ISD::CCDChip*,double, IPState)), this, SLOT(updateCaptureProgress(ISD::CCDChip*,double,IPState)));
-
- currentCCD->setFITSDir("");
-
- imgProgress->reset();
- imgProgress->setEnabled(false);
-
- fullImgCountOUT->setText(QString());
- currentImgCountOUT->setText(QString());
- exposeOUT->setText(QString());
-
- setBusy(false);
-
- if (abort)
- {
- startB->setIcon(QIcon::fromTheme("media-playback-start"));
- startB->setToolTip(i18n("Start Sequence"));
- pauseB->setEnabled(false);
- }
-
- foreach (QAbstractButton *button, queueEditButtonGroup->buttons())
- button->setEnabled(true);
-
- seqTimer->stop();
-
-}
-
-void Capture::sendNewImage(QImage *image, ISD::CCDChip *myChip)
-{
- if (activeJob && myChip != guideChip)
- emit newImage(image, activeJob);
-}
-
-bool Capture::setCCD(QString device)
-{
- for (int i=0; i < CCDCaptureCombo->count(); i++)
- if (device == CCDCaptureCombo->itemText(i))
- {
- CCDCaptureCombo->setCurrentIndex(i);
- return true;
- }
-
- return false;
-}
-
-void Capture::checkCCD(int ccdNum)
-{
- if (ccdNum == -1)
- {
- ccdNum = CCDCaptureCombo->currentIndex();
-
- if (ccdNum == -1)
- return;
- }
-
- foreach(ISD::CCD *ccd, CCDs)
- {
- disconnect(ccd, SIGNAL(numberUpdated(INumberVectorProperty*)), this, SLOT(processCCDNumber(INumberVectorProperty*)));
- disconnect(ccd, SIGNAL(newTemperatureValue(double)), this, SLOT(updateCCDTemperature(double)));
- disconnect(ccd, SIGNAL(newRemoteFile(QString)), this, SLOT(setNewRemoteFile(QString)));
- }
-
- if (ccdNum <= CCDs.count())
- {
- // Check whether main camera or guide head only
- currentCCD = CCDs.at(ccdNum);
-
- if (CCDCaptureCombo->itemText(ccdNum).right(6) == QString("Guider"))
- {
- useGuideHead = true;
- targetChip = currentCCD->getChip(ISD::CCDChip::GUIDE_CCD);
- }
- else
- {
- currentCCD = CCDs.at(ccdNum);
- targetChip = currentCCD->getChip(ISD::CCDChip::PRIMARY_CCD);
- useGuideHead = false;
- }
-
- if (currentCCD->hasCooler())
- {
-
- temperatureCheck->setEnabled(true);
- temperatureIN->setEnabled(true);
-
- if (currentCCD->getBaseDevice()->getPropertyPermission("CCD_TEMPERATURE") != IP_RO)
- {
- double min,max,step;
- setTemperatureB->setEnabled(true);
- temperatureIN->setReadOnly(false);
- currentCCD->getMinMaxStep("CCD_TEMPERATURE", "CCD_TEMPERATURE_VALUE", &min, &max, &step);
- temperatureIN->setMinimum(min);
- temperatureIN->setMaximum(max);
- temperatureIN->setSingleStep(1);
- }
- else
- {
- setTemperatureB->setEnabled(false);
- temperatureIN->setReadOnly(true);
- }
-
- double temperature=0;
- if (currentCCD->getTemperature(&temperature))
- {
- temperatureOUT->setText(QString::number(temperature, 'f', 2));
- if (temperatureIN->cleanText().isEmpty())
- temperatureIN->setValue(temperature);
- }
- }
- else
- {
- temperatureCheck->setEnabled(false);
- temperatureIN->setEnabled(false);
- temperatureIN->clear();
- setTemperatureB->setEnabled(false);
- }
-
- updateFrameProperties();
-
- QStringList frameTypes = targetChip->getFrameTypes();
-
- frameTypeCombo->clear();
-
- if (frameTypes.isEmpty())
- frameTypeCombo->setEnabled(false);
- else
- {
- frameTypeCombo->setEnabled(true);
- frameTypeCombo->addItems(frameTypes);
- frameTypeCombo->setCurrentIndex(targetChip->getFrameType());
- }
-
- QStringList isoList = targetChip->getISOList();
- ISOCombo->clear();
-
- if (isoList.isEmpty())
- {
- ISOCombo->setEnabled(false);
- ISOLabel->setEnabled(false);
- }
- else
- {
- ISOCombo->setEnabled(true);
- ISOLabel->setEnabled(true);
- ISOCombo->addItems(isoList);
- ISOCombo->setCurrentIndex(targetChip->getISOIndex());
- }
-
- connect(currentCCD, SIGNAL(numberUpdated(INumberVectorProperty*)), this, SLOT(processCCDNumber(INumberVectorProperty*)), Qt::UniqueConnection);
- connect(currentCCD, SIGNAL(newTemperatureValue(double)), this, SLOT(updateCCDTemperature(double)), Qt::UniqueConnection);
- connect(currentCCD, SIGNAL(newRemoteFile(QString)), this, SLOT(setNewRemoteFile(QString)));
- }
-}
-
-void Capture::updateFrameProperties(bool reset)
-{
- int x,y,w,h;
- int binx=1,biny=1;
- double min,max,step;
- int xstep=0, ystep=0;
-
- QString frameProp = useGuideHead ? QString("GUIDER_FRAME") : QString("CCD_FRAME");
- QString exposureProp = useGuideHead ? QString("GUIDER_EXPOSURE") : QString("CCD_EXPOSURE");
- QString exposureElem = useGuideHead ? QString("GUIDER_EXPOSURE_VALUE") : QString("CCD_EXPOSURE_VALUE");
- targetChip = useGuideHead ? currentCCD->getChip(ISD::CCDChip::GUIDE_CCD) : currentCCD->getChip(ISD::CCDChip::PRIMARY_CCD);
-
- frameWIN->setEnabled(targetChip->canSubframe());
- frameHIN->setEnabled(targetChip->canSubframe());
- frameXIN->setEnabled(targetChip->canSubframe());
- frameYIN->setEnabled(targetChip->canSubframe());
-
- binXIN->setEnabled(targetChip->canBin());
- binYIN->setEnabled(targetChip->canBin());
-
- if (currentCCD->getMinMaxStep(exposureProp, exposureElem, &min, &max, &step))
- {
- exposureIN->setMinimum(min);
- exposureIN->setMaximum(max);
- exposureIN->setSingleStep(step);
- }
-
- if (currentCCD->getMinMaxStep(frameProp, "WIDTH", &min, &max, &step))
- {
-
- if (min == max)
- return;
-
- if (step == 0)
- xstep = (int) max * 0.05;
- else
- xstep = step;
-
- if (min >= 0 && max > 0)
- {
- frameWIN->setMinimum(min);
- frameWIN->setMaximum(max);
- frameWIN->setSingleStep(xstep);
- }
- }
- else
- return;
-
- if (currentCCD->getMinMaxStep(frameProp, "HEIGHT", &min, &max, &step))
- {
- if (min == max)
- return;
-
- if (step == 0)
- ystep = (int) max * 0.05;
- else
- ystep = step;
-
- if (min >= 0 && max > 0)
- {
- frameHIN->setMinimum(min);
- frameHIN->setMaximum(max);
- frameHIN->setSingleStep(ystep);
- }
- }
- else
- return;
-
- if (currentCCD->getMinMaxStep(frameProp, "X", &min, &max, &step))
- {
- if (min == max)
- return;
-
- if (step == 0)
- step = xstep;
-
- if (min >= 0 && max > 0)
- {
- frameXIN->setMinimum(min);
- frameXIN->setMaximum(max);
- frameXIN->setSingleStep(step);
- }
- }
- else
- return;
-
- if (currentCCD->getMinMaxStep(frameProp, "Y", &min, &max, &step))
- {
- if (min == max)
- return;
-
- if (step == 0)
- step = ystep;
-
- if (min >= 0 && max > 0)
- {
- frameYIN->setMinimum(min);
- frameYIN->setMaximum(max);
- frameYIN->setSingleStep(step);
- }
- }
- else
- return;
-
- if (reset || frameSettings.contains(targetChip) == false)
- {
- QVariantMap settings;
-
- settings["x"] = 0;
- settings["y"] = 0;
- settings["w"] = frameWIN->maximum();
- settings["h"] = frameHIN->maximum();
- settings["binx"] = 1;
- settings["biny"] = 1;
-
- frameSettings[targetChip] = settings;
- }
-
- if (frameSettings.contains(targetChip))
- {
- QVariantMap settings = frameSettings[targetChip];
-
- if (targetChip->canBin())
- {
- targetChip->getMaxBin(&binx, &biny);
- binXIN->setMaximum(binx);
- binYIN->setMaximum(biny);
-
- binXIN->setValue(settings["binx"].toInt());
- binYIN->setValue(settings["biny"].toInt());
- }
- else
- {
- binXIN->setValue(1);
- binYIN->setValue(1);
- }
-
- x = settings["x"].toInt();
- y = settings["y"].toInt();
- w = settings["w"].toInt();
- h = settings["h"].toInt();
-
- if (x >= 0)
- frameXIN->setValue(x);
- if (y >= 0)
- frameYIN->setValue(y);
- if (w > 0)
- frameWIN->setValue(w);
- if (h > 0)
- frameHIN->setValue(h);
- }
-}
-
-void Capture::processCCDNumber(INumberVectorProperty *nvp)
-{
- if (currentCCD && ( (!strcmp(nvp->name, "CCD_FRAME") && useGuideHead == false) || (!strcmp(nvp->name, "GUIDER_FRAME") && useGuideHead)))
- updateFrameProperties();
-}
-
-void Capture::resetFrame()
-{
- targetChip = useGuideHead ? currentCCD->getChip(ISD::CCDChip::GUIDE_CCD) : currentCCD->getChip(ISD::CCDChip::PRIMARY_CCD);
- targetChip->resetFrame();
- updateFrameProperties(true);
-}
-
-void Capture::syncFrameType(ISD::GDInterface *ccd)
-{
- if (strcmp(ccd->getDeviceName(), CCDCaptureCombo->currentText().toLatin1()))
- return;
-
- ISD::CCDChip *tChip = NULL;
- tChip = (static_cast<ISD::CCD *> (ccd) )->getChip(ISD::CCDChip::PRIMARY_CCD);
-
- QStringList frameTypes = tChip->getFrameTypes();
-
- frameTypeCombo->clear();
-
- if (frameTypes.isEmpty())
- frameTypeCombo->setEnabled(false);
- else
- {
- frameTypeCombo->setEnabled(true);
- frameTypeCombo->addItems(frameTypes);
- frameTypeCombo->setCurrentIndex(tChip->getFrameType());
- }
-
-
-}
-
-bool Capture::setFilter(QString device, int filterSlot)
-{
- bool deviceFound=false;
-
- for (int i=0; i < FilterCaptureCombo->count(); i++)
- if (device == FilterCaptureCombo->itemText(i))
- {
- checkFilter(i);
- deviceFound = true;
- break;
- }
-
- if (deviceFound == false)
- return false;
-
- if (filterSlot < FilterCaptureCombo->count())
- FilterCaptureCombo->setCurrentIndex(filterSlot);
-
- return true;
-}
-
-void Capture::checkFilter(int filterNum)
-{
-
- if (filterNum == -1)
- {
- filterNum = FilterCaptureCombo->currentIndex();
- if (filterNum == -1)
- return;
- }
-
-
- QStringList filterAlias = Options::filterAlias();
-
- if (filterNum <= Filters.count())
- currentFilter = Filters.at(filterNum);
-
- syncFilterInfo();
-
- FilterPosCombo->clear();
-
- filterName = currentFilter->getBaseDevice()->getText("FILTER_NAME");
- filterSlot = currentFilter->getBaseDevice()->getNumber("FILTER_SLOT");
-
- if (filterSlot == NULL)
- {
- KMessageBox::error(0, i18n("Unable to find FILTER_SLOT property in driver %1", currentFilter->getBaseDevice()->getDeviceName()));
- return;
- }
-
- for (int i=0; i < filterSlot->np[0].max; i++)
- {
- QString item;
-
- if (filterName != NULL && (i < filterName->ntp))
- item = filterName->tp[i].text;
- else if (i < filterAlias.count() && filterAlias[i].isEmpty() == false)
- item = filterAlias.at(i);
- else
- item = QString("Filter_%1").arg(i+1);
-
- FilterPosCombo->addItem(item);
-
- }
-
- FilterPosCombo->setCurrentIndex( (int) filterSlot->np[0].value-1);
-
- currentFilterPosition = (int) filterSlot->np[0].value;
-
- if (activeJob && (activeJob->getStatus() == SequenceJob::JOB_ABORTED || activeJob->getStatus() == SequenceJob::JOB_IDLE))
- activeJob->setCurrentFilter(currentFilterPosition);
-
-}
-
-void Capture::syncFilterInfo()
-{
- if (currentCCD && currentFilter)
- {
- ITextVectorProperty *activeDevices = currentCCD->getBaseDevice()->getText("ACTIVE_DEVICES");
- if (activeDevices)
- {
- IText *activeFilter = IUFindText(activeDevices, "ACTIVE_FILTER");
- if (activeFilter && strcmp(activeFilter->text, currentFilter->getDeviceName()))
- {
- IUSaveText(activeFilter, currentFilter->getDeviceName());
- currentCCD->getDriverInfo()->getClientManager()->sendNewText(activeDevices);
- }
- }
- }
-}
-
-bool Capture::startNextExposure()
-{
- if (state == CAPTURE_PAUSED)
- {
- pauseFunction = &Capture::startNextExposure;
- appendLogText(i18n("Sequence paused."));
- secondsLabel->setText(i18n("Paused..."));
- return false;
- }
-
- if (seqDelay > 0)
- {
- secondsLabel->setText(i18n("Waiting..."));
- state = CAPTURE_WAITING;
- emit newStatus(Ekos::CAPTURE_WAITING);
- }
-
- seqTimer->start(seqDelay);
-
- return true;
-}
-
-void Capture::newFITS(IBLOB *bp)
-{
- ISD::CCDChip *tChip = NULL;
-
- // If there is no active job, ignore
- if (activeJob == NULL || meridianFlipStage >= MF_ALIGNING)
- return;
-
- if (currentCCD->getUploadMode() != ISD::CCD::UPLOAD_LOCAL)
- {
- if (bp == NULL)
- {
- abort();
- return;
- }
-
- if (!strcmp(bp->name, "CCD2"))
- tChip = currentCCD->getChip(ISD::CCDChip::GUIDE_CCD);
- else
- tChip = currentCCD->getChip(ISD::CCDChip::PRIMARY_CCD);
-
- if (tChip != targetChip)
- return;
-
- if (targetChip->getCaptureMode() == FITS_FOCUS || targetChip->getCaptureMode() == FITS_GUIDE)
- return;
-
- // If this is a preview job, make sure to enable preview button after
- // we receive the FITS
- if (activeJob->isPreview() && previewB->isEnabled() == false)
- previewB->setEnabled(true);
-
- // If the FITS is not for our device, simply ignore
- //if (QString(bp->bvp->device) != currentCCD->getDeviceName() || (startB->isEnabled() && previewB->isEnabled()))
- if (QString(bp->bvp->device) != currentCCD->getDeviceName() || state == CAPTURE_IDLE)
- return;
-
- disconnect(currentCCD, SIGNAL(BLOBUpdated(IBLOB*)), this, SLOT(newFITS(IBLOB*)));
- disconnect(currentCCD, SIGNAL(newImage(QImage*, ISD::CCDChip*)), this, SLOT(sendNewImage(QImage*, ISD::CCDChip*)));
-
- if (useGuideHead == false && darkSubCheck->isChecked() && activeJob->isPreview())
- {
- FITSView *currentImage = targetChip->getImage(FITS_NORMAL);
- FITSData *darkData = NULL;
- uint16_t offsetX = activeJob->getSubX() / activeJob->getXBin();
- uint16_t offsetY = activeJob->getSubY() / activeJob->getYBin();
-
- darkData = DarkLibrary::Instance()->getDarkFrame(targetChip, activeJob->getExposure());
-
- connect(DarkLibrary::Instance(), SIGNAL(darkFrameCompleted(bool)), this, SLOT(setCaptureComplete()));
- connect(DarkLibrary::Instance(), SIGNAL(newLog(QString)), this, SLOT(appendLogText(QString)));
-
- if (darkData)
- DarkLibrary::Instance()->subtract(darkData, currentImage, activeJob->getCaptureFilter(), offsetX, offsetY);
- else
- DarkLibrary::Instance()->captureAndSubtract(targetChip, currentImage, activeJob->getExposure(), offsetX, offsetY);
-
- return;
- }
- }
-
- setCaptureComplete();
-
-}
-
-bool Capture::setCaptureComplete()
-{
- disconnect(currentCCD, SIGNAL(newExposureValue(ISD::CCDChip*,double,IPState)), this, SLOT(updateCaptureProgress(ISD::CCDChip*,double,IPState)));
- DarkLibrary::Instance()->disconnect(this);
- secondsLabel->setText(i18n("Complete."));
-
- // If it was initially set as preview job
- if (seqTotalCount <= 0)
- {
- jobs.removeOne(activeJob);
- delete(activeJob);
- // Reset active job pointer
- activeJob = NULL;
- abort();
- return true;
- }
-
- if (state == CAPTURE_PAUSED)
- {
- pauseFunction = &Capture::setCaptureComplete;
- appendLogText(i18n("Sequence paused."));
- secondsLabel->setText(i18n("Paused..."));
- return false;
- }
-
- if (activeJob->getFrameType() != FRAME_LIGHT)
- {
- if (processPostCaptureCalibrationStage() == false)
- return true;
-
- if (calibrationStage == CAL_CALIBRATION_COMPLETE)
- calibrationStage = CAL_CAPTURING;
- }
-
- seqCurrentCount++;
- activeJob->setCompleted(seqCurrentCount);
- imgProgress->setValue(seqCurrentCount);
-
- appendLogText(i18n("Received image %1 out of %2.", seqCurrentCount, seqTotalCount));
-
- state = CAPTURE_IMAGE_RECEIVED;
- emit newStatus(Ekos::CAPTURE_IMAGE_RECEIVED);
-
- currentImgCountOUT->setText( QString::number(seqCurrentCount));
-
- // if we're done
- if (seqCurrentCount >= seqTotalCount)
- {
- processJobCompletion();
- return true;
- }
-
- // Check if meridian condition is met
- if (checkMeridianFlip())
- return true;
-
- // FIXME remove post capture script later
- if (Options::postCaptureScript().isEmpty() == false)
- {
- postCaptureScript.start(Options::postCaptureScript());
- appendLogText(i18n("Executing post capture script %1", Options::postCaptureScript()));
- }
- else
- resumeSequence();
-
- return true;
-}
-
-void Capture::processJobCompletion()
-{
- activeJob->done();
-
- stop();
-
- // Check if meridian condition is met
- if (checkMeridianFlip())
- return;
-
- // Check if there are more pending jobs and execute them
- if (resumeSequence())
- return;
- // Otherwise, we're done. We park if required and resume guiding if no parking is done and autoguiding was engaged before.
- else
- {
- KNotification::event( QLatin1String( "CaptureSuccessful"), i18n("CCD capture sequence completed"));
-
- abort();
-
- state = CAPTURE_COMPLETE;
- emit newStatus(Ekos::CAPTURE_COMPLETE);
-
- if (parkCheck->isChecked() && currentTelescope && currentTelescope->canPark())
- {
- appendLogText(i18n("Parking telescope..."));
- //emit mountParking();
- currentTelescope->Park();
- return;
- }
-
- //Resume guiding if it was suspended before
- //if (isAutoGuiding && currentCCD->getChip(ISD::CCDChip::GUIDE_CCD) == guideChip)
- if (guideState == GUIDE_SUSPENDED && currentCCD->getChip(ISD::CCDChip::GUIDE_CCD) == guideChip)
- emit suspendGuiding(false);
- }
-
-}
-
-bool Capture::resumeSequence()
-{
- if (state == CAPTURE_PAUSED)
- {
- pauseFunction = &Capture::resumeSequence;
- appendLogText(i18n("Sequence paused."));
- secondsLabel->setText(i18n("Paused..."));
- return false;
- }
-
- // If seqTotalCount is zero, we have to find if there are more pending jobs in the queue
- if (seqTotalCount == 0)
- {
- SequenceJob *next_job = NULL;
-
- foreach(SequenceJob *job, jobs)
- {
- if (job->getStatus() == SequenceJob::JOB_IDLE || job->getStatus() == SequenceJob::JOB_ABORTED)
- {
- next_job = job;
- break;
- }
- }
-
- if (next_job)
- {
- prepareJob(next_job);
-
- //Resume guiding if it was suspended before
- //if (isAutoGuiding && currentCCD->getChip(ISD::CCDChip::GUIDE_CCD) == guideChip)
- if (guideState == GUIDE_SUSPENDED && currentCCD->getChip(ISD::CCDChip::GUIDE_CCD) == guideChip)
- emit suspendGuiding(false);
-
- return true;
- }
- else
- return false;
- }
- // Otherwise, let's prepare for next exposure after making sure in-sequence focus and dithering are complete if applicable.
- else
- {
- isAutoFocus = (autofocusCheck->isEnabled() && autofocusCheck->isChecked() && HFRPixels->value() > 0);
- if (isAutoFocus)
- autoFocusStatus = false;
-
- // Reset HFR pixels to zero after merdian flip
- if (isAutoFocus && meridianFlipStage != MF_NONE)
- {
- firstAutoFocus=true;
- HFRPixels->setValue(fileHFR);
- }
-
- // If we suspended guiding due to primary chip download, resume guide chip guiding now
- if (guideState == GUIDE_SUSPENDED && currentCCD->getChip(ISD::CCDChip::GUIDE_CCD) == guideChip)
- emit suspendGuiding(false);
-
- //if (isAutoGuiding && guideDither && activeJob->getFrameType() == FRAME_LIGHT)
- if (guideState == GUIDE_GUIDING && guideDither && activeJob->getFrameType() == FRAME_LIGHT)
- {
- secondsLabel->setText(i18n("Dithering..."));
- //emit exposureComplete();
-
- state = CAPTURE_DITHERING;
- emit newStatus(Ekos::CAPTURE_DITHERING);
- }
- else if (isAutoFocus && activeJob->getFrameType() == FRAME_LIGHT)
- {
- secondsLabel->setText(i18n("Focusing..."));
- emit checkFocus(HFRPixels->value());
-
- state = CAPTURE_FOCUSING;
- emit newStatus(Ekos::CAPTURE_FOCUSING);
- }
- else
- startNextExposure();
- }
-
- return true;
-}
-
-void Capture::captureOne()
-{
- if (currentCCD->getUploadMode() == ISD::CCD::UPLOAD_LOCAL)
- {
- appendLogText(i18n("Cannot take preview image while CCD upload mode is set to local. Please change upload mode to client and try again."));
- return;
- }
-
- addJob(true);
-
- prepareJob(jobs.last());
-}
-
-void Capture::captureImage()
-{
- seqTimer->stop();
- //bool isDark=false;
- SequenceJob::CAPTUREResult rc=SequenceJob::CAPTURE_OK;
-
- if (focusState >= FOCUS_PROGRESS)
- {
- appendLogText(i18n("Cannot capture while focus module is busy."));
- abort();
- return;
- }
-
- //if (useGuideHead == false && darkSubCheck->isChecked() && calibrationState == CALIBRATE_NONE)
- //isDark = true;
-
- if (filterSlot != NULL)
- {
- currentFilterPosition = (int) filterSlot->np[0].value;
- activeJob->setCurrentFilter(currentFilterPosition);
- }
-
- if (currentCCD->hasCooler())
- {
- double temperature=0;
- currentCCD->getTemperature(&temperature);
- activeJob->setCurrentTemperature(temperature);
- }
-
- connect(currentCCD, SIGNAL(BLOBUpdated(IBLOB*)), this, SLOT(newFITS(IBLOB*)), Qt::UniqueConnection);
- connect(currentCCD, SIGNAL(newImage(QImage*, ISD::CCDChip*)), this, SLOT(sendNewImage(QImage*, ISD::CCDChip*)), Qt::UniqueConnection);
-
- if (activeJob->getFrameType() == FRAME_FLAT)
- {
- // If we have to calibrate ADU levels, first capture must be preview and not in batch mode
- if (activeJob->isPreview() == false && activeJob->getFlatFieldDuration() == DURATION_ADU && calibrationStage == CAL_PRECAPTURE_COMPLETE)
- {
- calibrationStage = CAL_CALIBRATION;
- activeJob->setPreview(true);
- }
- }
-
- if (currentCCD->getUploadMode() != ISD::CCD::UPLOAD_LOCAL)
- checkSeqBoundary(activeJob->getFITSDir());
-
- state = CAPTURE_CAPTURING;
-
- if (activeJob->isPreview() == false)
- emit newStatus(Ekos::CAPTURE_CAPTURING);
-
- if (frameSettings.contains(activeJob->getActiveChip()))
- {
- QVariantMap settings;
- settings["x"] = activeJob->getSubX();
- settings["y"] = activeJob->getSubY();
- settings["w"] = activeJob->getSubW();
- settings["h"] = activeJob->getSubH();
- settings["binx"] = activeJob->getXBin();
- settings["biny"] = activeJob->getYBin();
-
- frameSettings[activeJob->getActiveChip()] = settings;
- }
-
- rc = activeJob->capture(darkSubCheck->isChecked() ? true : false);
-
- switch (rc)
- {
- case SequenceJob::CAPTURE_OK:
- connect(currentCCD, SIGNAL(newExposureValue(ISD::CCDChip*,double,IPState)), this, SLOT(updateCaptureProgress(ISD::CCDChip*,double,IPState)), Qt::UniqueConnection);
- appendLogText(i18n("Capturing image..."));
- break;
-
- case SequenceJob::CAPTURE_FRAME_ERROR:
- appendLogText(i18n("Failed to set sub frame."));
- abort();
- break;
-
- case SequenceJob::CAPTURE_BIN_ERROR:
- appendLogText(i18n("Failed to set binning."));
- abort();
- break;
-
- case SequenceJob::CAPTURE_FILTER_BUSY:
- // Try again in 1 second if filter is busy
- QTimer::singleShot(1000, this, SLOT(captureImage()));
- break;
-
- case SequenceJob::CAPTURE_FOCUS_ERROR:
- appendLogText(i18n("Cannot capture while focus module is busy."));
- abort();
- break;
-
- }
-}
-
-bool Capture::resumeCapture()
-{
- if (state == CAPTURE_PAUSED)
- {
- pauseFunction = &Capture::resumeCapture;
- appendLogText(i18n("Sequence paused."));
- secondsLabel->setText(i18n("Paused..."));
- return false;
- }
-
- appendLogText(i18n("Dither complete."));
-
- if (isAutoFocus && autoFocusStatus == false)
- {
- secondsLabel->setText(i18n("Focusing..."));
- emit checkFocus(HFRPixels->value());
- state = CAPTURE_FOCUSING;
- emit newStatus(Ekos::CAPTURE_FOCUSING);
- return true;
- }
-
- startNextExposure();
-
- return true;
-}
-
-/*******************************************************************************/
-/* Update the prefix for the sequence of images to be captured */
-/*******************************************************************************/
-void Capture::updateSequencePrefix( const QString &newPrefix, const QString &dir)
-{
- //static QString lastDir=QDir::homePath();
-
- seqPrefix = newPrefix;
-
- // If it doesn't exist, create it
- QDir().mkpath(dir);
-
- /*if (dir != lastDir)
- {
- seqWatcher->removeDir(lastDir);
- lastDir = dir;
- }
-
- seqWatcher->addDir(dir, KDirWatch::WatchFiles);*/
-
- nextSequenceID = 1;
-
- //checkSeqBoundary(dir);
-}
-
-/*void Capture::checkSeqFile(const QString &path)
-{
- checkSeqBoundary(QFileInfo(path).absolutePath());
-}*/
-
-/*******************************************************************************/
-/* Determine the next file number sequence. That is, if we have file1.png */
-/* and file2.png, then the next sequence should be file3.png */
-/*******************************************************************************/
-void Capture::checkSeqBoundary(const QString &path)
-{
- int newFileIndex=-1;
- QString tempName;
- seqFileCount=0;
-
- // No updates during meridian flip
- if (meridianFlipStage >= MF_ALIGNING)
- return;
-
- QDirIterator it(path, QDir::Files);
-
- while (it.hasNext())
- {
- tempName = it.next();
- QFileInfo info(tempName);
- tempName = info.baseName();
-
- // find the prefix first
- if (tempName.startsWith(seqPrefix) == false)
- continue;
-
- seqFileCount++;
-
- tempName = tempName.remove(seqPrefix);
-
- if (tempName.startsWith("_"))
- tempName = tempName.remove(0, 1);
-
- bool indexOK = false;
- newFileIndex = tempName.mid(0, 3).toInt(&indexOK);
-
- if (indexOK && newFileIndex >= nextSequenceID)
- nextSequenceID = newFileIndex + 1;
- }
-
- currentCCD->setNextSequenceID(nextSequenceID);
-}
-
-void Capture::appendLogText(const QString &text)
-{
- logText.insert(0, i18nc("log entry; %1 is the date, %2 is the text", "%1 %2", QDateTime::currentDateTime().toString("yyyy-MM-ddThh:mm:ss"), text));
-
- if (Options::captureLogging())
- qDebug() << "Capture: " << text;
-
- emit newLog();
-}
-
-void Capture::clearLog()
-{
- logText.clear();
- emit newLog();
-}
-
-void Capture::updateCaptureProgress(ISD::CCDChip * tChip, double value, IPState state)
-{
-
- if (targetChip != tChip || targetChip->getCaptureMode() != FITS_NORMAL || meridianFlipStage >= MF_ALIGNING)
- return;
-
- exposeOUT->setText(QString::number(value, 'd', 2));
-
- if (activeJob)
- activeJob->setExposeLeft(value);
-
- if (activeJob && state == IPS_ALERT)
- {
- int retries = activeJob->getCaptureRetires()+1;
-
- activeJob->setCaptureRetires(retries);
-
- appendLogText(i18n("Capture failed."));
-
- if (retries == 3)
- {
- abort();
- return;
- }
-
- appendLogText(i18n("Restarting capture attempt #%1", retries));
-
- nextSequenceID = 1;
-
- captureImage();
- return;
- }
-
- if (value == 0)
- {
- activeJob->setCaptureRetires(0);
-
- if (currentCCD && currentCCD->getUploadMode() == ISD::CCD::UPLOAD_LOCAL)
- {
- if (activeJob && activeJob->getStatus() == SequenceJob::JOB_BUSY && activeJob->getExposeLeft() == 0 && state == IPS_OK)
- {
- newFITS(0);
- return;
- }
- }
-
- //if (isAutoGuiding && Options::useEkosGuider() && currentCCD->getChip(ISD::CCDChip::GUIDE_CCD) == guideChip)
- if (guideState == GUIDE_GUIDING && Options::useEkosGuider() && currentCCD->getChip(ISD::CCDChip::GUIDE_CCD) == guideChip)
- {
- if (Options::captureLogging())
- qDebug() << "Capture: Autoguiding suspended until primary CCD chip completes downloading...";
- emit suspendGuiding(true);
- }
-
- secondsLabel->setText(i18n("Downloading..."));
-
- //disconnect(currentCCD, SIGNAL(newExposureValue(ISD::CCDChip*,double,IPState)), this, SLOT(updateCaptureProgress(ISD::CCDChip*,double,IPState)));
- }
- // JM: Don't change to i18np, value is DOUBLE, not Integer.
- else if (value <= 1)
- secondsLabel->setText(i18n("second left"));
- else
- secondsLabel->setText(i18n("seconds left"));
-}
-
-void Capture::updateCCDTemperature(double value)
-{
- if (temperatureCheck->isEnabled() == false)
- checkCCD();
-
- temperatureOUT->setText(QString::number(value, 'f', 2));
-
- if (activeJob && (activeJob->getStatus() == SequenceJob::JOB_ABORTED || activeJob->getStatus() == SequenceJob::JOB_IDLE))
- activeJob->setCurrentTemperature(value);
-}
-
-void Capture::addJob(bool preview)
-{
- SequenceJob *job = NULL;
- QString imagePrefix;
-
- if (preview == false && darkSubCheck->isChecked())
- {
- KMessageBox::error(this, i18n("Auto dark subtract is not supported in batch mode."));
- return;
- }
-
- if (jobUnderEdit)
- job = jobs.at(queueTable->currentRow());
- else
- job = new SequenceJob();
-
- if (job == NULL)
- {
- qWarning() << "Job is NULL!" << endl;
- return;
- }
-
- if (ISOCombo->isEnabled())
- job->setISOIndex(ISOCombo->currentIndex());
-
- job->setPreview(preview);
-
- if (temperatureIN->isEnabled())
- {
- double currentTemperature;
- currentCCD->getTemperature(&currentTemperature);
- job->setEnforceTemperature(temperatureCheck->isChecked());
- job->setTargetTemperature(temperatureIN->value());
- job->setCurrentTemperature(currentTemperature);
- }
-
- job->setCaptureFilter((FITSScale) filterCombo->currentIndex());
-
- job->setFlatFieldDuration(flatFieldDuration);
- job->setFlatFieldSource(flatFieldSource);
- job->setPreMountPark(preMountPark);
- job->setPreDomePark(preDomePark);
- job->setWallCoord(wallCoord);
- job->setTargetADU(targetADU);
-
- imagePrefix = prefixIN->text();
-
- constructPrefix(imagePrefix);
-
- job->setPrefixSettings(prefixIN->text(), filterCheck->isChecked(), expDurationCheck->isChecked(), ISOCheck->isChecked());
- job->setFrameType(frameTypeCombo->currentIndex(), frameTypeCombo->currentText());
- job->setFullPrefix(imagePrefix);
-
- if (filterSlot != NULL && currentFilter != NULL)
- job->setTargetFilter(FilterPosCombo->currentIndex()+1, FilterPosCombo->currentText());
-
- job->setExposure(exposureIN->value());
-
- job->setCount(countIN->value());
-
- job->setBin(binXIN->value(), binYIN->value());
-
- job->setDelay(delayIN->value() * 1000); /* in ms */
-
- job->setActiveChip(targetChip);
- job->setActiveCCD(currentCCD);
- job->setActiveFilter(currentFilter);
-
- job->setFrame(frameXIN->value(), frameYIN->value(), frameWIN->value(), frameHIN->value());
-
- job->setRootFITSDir(fitsDir->text());
-
- if (jobUnderEdit == false)
- {
- jobs.append(job);
-
- // Nothing more to do if preview
- if (preview)
- return;
- }
-
- QString finalFITSDir = fitsDir->text();
-
- if (targetName.isEmpty())
- finalFITSDir += QLatin1Literal("/") + frameTypeCombo->currentText();
- else
- finalFITSDir += QLatin1Literal("/") + targetName + QLatin1Literal("/") + frameTypeCombo->currentText();
- if ( (job->getFrameType() == FRAME_LIGHT || job->getFrameType() == FRAME_FLAT) && job->getFilterName().isEmpty() == false)
- finalFITSDir += QLatin1Literal("/") + job->getFilterName();
-
- job->setFITSDir(finalFITSDir);
-
- int currentRow = 0;
- if (jobUnderEdit == false)
- {
- currentRow = queueTable->rowCount();
- queueTable->insertRow(currentRow);
- }
- else
- currentRow = queueTable->currentRow();
-
- QTableWidgetItem *status = jobUnderEdit ? queueTable->item(currentRow, 0) : new QTableWidgetItem();
- status->setText(job->getStatusString());
- status->setTextAlignment(Qt::AlignHCenter);
- status->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
-
- job->setStatusCell(status);
-
- QTableWidgetItem *filter = jobUnderEdit ? queueTable->item(currentRow, 1) : new QTableWidgetItem();
- filter->setText("--");
- if (frameTypeCombo->currentText().compare("Bias", Qt::CaseInsensitive) &&
- frameTypeCombo->currentText().compare("Dark", Qt::CaseInsensitive) &&
- FilterPosCombo->count() > 0)
- filter->setText(FilterPosCombo->currentText());
-
- filter->setTextAlignment(Qt::AlignHCenter);
- filter->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
-
- QTableWidgetItem *type = jobUnderEdit ? queueTable->item(currentRow, 2) : new QTableWidgetItem();
- type->setText(frameTypeCombo->currentText());
- type->setTextAlignment(Qt::AlignHCenter);
- type->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
-
- QTableWidgetItem *bin = jobUnderEdit ? queueTable->item(currentRow, 3) : new QTableWidgetItem();
- bin->setText(QString("%1x%2").arg(binXIN->value()).arg(binYIN->value()));
- bin->setTextAlignment(Qt::AlignHCenter);
- bin->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
-
- QTableWidgetItem *exp = jobUnderEdit ? queueTable->item(currentRow, 4) : new QTableWidgetItem();
- exp->setText(QString::number(exposureIN->value()));
- exp->setTextAlignment(Qt::AlignHCenter);
- exp->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
-
- QTableWidgetItem *iso = jobUnderEdit ? queueTable->item(currentRow, 5) : new QTableWidgetItem();
- if (ISOCombo->currentIndex() != -1)
- iso->setText(ISOCombo->currentText());
- else
- iso->setText("--");
- iso->setTextAlignment(Qt::AlignHCenter);
- iso->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
-
-
- QTableWidgetItem *count = jobUnderEdit ? queueTable->item(currentRow, 6) : new QTableWidgetItem();
- count->setText(QString::number(countIN->value()));
- count->setTextAlignment(Qt::AlignHCenter);
- count->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
-
- if (jobUnderEdit == false)
- {
- queueTable->setItem(currentRow, 0, status);
- queueTable->setItem(currentRow, 1, filter);
- queueTable->setItem(currentRow, 2, type);
- queueTable->setItem(currentRow, 3, bin);
- queueTable->setItem(currentRow, 4, exp);
- queueTable->setItem(currentRow, 5, iso);
- queueTable->setItem(currentRow, 6, count);
- }
-
- removeFromQueueB->setEnabled(true);
-
- if (queueTable->rowCount() > 0)
- {
- queueSaveAsB->setEnabled(true);
- queueSaveB->setEnabled(true);
- resetB->setEnabled(true);
- mDirty = true;
- }
-
- if (queueTable->rowCount() > 1)
- {
- queueUpB->setEnabled(true);
- queueDownB->setEnabled(true);
- }
-
- if (jobUnderEdit)
- {
- jobUnderEdit = false;
- resetJobEdit();
- appendLogText(i18n("Job #%1 changes applied.", currentRow+1));
- }
-
-}
-
-void Capture::removeJob()
-{
- if (jobUnderEdit)
- {
- resetJobEdit();
- return;
- }
-
- int currentRow = queueTable->currentRow();
-
- if (currentRow < 0)
- {
- currentRow = queueTable->rowCount()-1;
- if (currentRow < 0)
- return;
- }
-
- queueTable->removeRow(currentRow);
-
- SequenceJob *job = jobs.at(currentRow);
- jobs.removeOne(job);
- delete (job);
-
- if (queueTable->rowCount() == 0)
- removeFromQueueB->setEnabled(false);
-
- if (queueTable->rowCount() == 1)
- {
- queueUpB->setEnabled(false);
- queueDownB->setEnabled(false);
- }
-
- for (int i=0; i < jobs.count(); i++)
- jobs.at(i)->setStatusCell(queueTable->item(i, 0));
-
- queueTable->selectRow(queueTable->currentRow());
-
- if (queueTable->rowCount() == 0)
- {
- queueSaveAsB->setEnabled(false);
- queueSaveB->setEnabled(false);
- resetB->setEnabled(false);
- }
-
- mDirty = true;
-
-
-}
-
-void Capture::moveJobUp()
-{
- int currentRow = queueTable->currentRow();
-
- int columnCount = queueTable->columnCount();
-
- if (currentRow <= 0 || queueTable->rowCount() == 1)
- return;
-
- int destinationRow = currentRow - 1;
-
- for (int i=0; i < columnCount; i++)
- {
- QTableWidgetItem *downItem = queueTable->takeItem(currentRow, i);
- QTableWidgetItem *upItem = queueTable->takeItem(destinationRow, i);
-
- queueTable->setItem(destinationRow, i, downItem);
- queueTable->setItem(currentRow, i, upItem);
- }
-
- SequenceJob *job = jobs.takeAt(currentRow);
-
- jobs.removeOne(job);
- jobs.insert(destinationRow, job);
-
- queueTable->selectRow(destinationRow);
-
- for (int i=0; i < jobs.count(); i++)
- jobs.at(i)->setStatusCell(queueTable->item(i, 0));
-
-
- mDirty = true;
-
-}
-
-void Capture::moveJobDown()
-{
- int currentRow = queueTable->currentRow();
-
- int columnCount = queueTable->columnCount();
-
- if (currentRow < 0 || queueTable->rowCount() == 1 || (currentRow+1) == queueTable->rowCount() )
- return;
-
- int destinationRow = currentRow + 1;
-
- for (int i=0; i < columnCount; i++)
- {
- QTableWidgetItem *downItem = queueTable->takeItem(currentRow, i);
- QTableWidgetItem *upItem = queueTable->takeItem(destinationRow, i);
-
- queueTable->setItem(destinationRow, i, downItem);
- queueTable->setItem(currentRow, i, upItem);
- }
-
- SequenceJob *job = jobs.takeAt(currentRow);
-
- jobs.removeOne(job);
- jobs.insert(destinationRow, job);
-
- queueTable->selectRow(destinationRow);
-
- for (int i=0; i < jobs.count(); i++)
- jobs.at(i)->setStatusCell(queueTable->item(i, 0));
-
- mDirty = true;
-
-}
-
-void Capture::setBusy(bool enable)
-{
- isBusy = enable;
-
- enable ? pi->startAnimation() : pi->stopAnimation();
- previewB->setEnabled(!enable);
- //startB->setEnabled(!enable);
- //stopB->setEnabled(enable);
-}
-
-void Capture::prepareJob(SequenceJob *job)
-{
- activeJob = job;
-
- // Just notification of active job stating up
- emit newImage(NULL, activeJob);
-
- connect(job, SIGNAL(checkFocus()), this, SLOT(startPostFilterAutoFocus()));
-
- // Reset calibration stage
- if (calibrationStage == CAL_CAPTURING)
- {
- if (job->getFrameType() != FRAME_LIGHT)
- calibrationStage = CAL_PRECAPTURE_COMPLETE;
- else
- calibrationStage = CAL_NONE;
- }
-
- if (currentFilterPosition > 0)
- {
- // If we haven't performed a single autofocus yet, we stop
- if (Options::autoFocusOnFilterChange() && (isAutoFocus == false && firstAutoFocus == true))
- {
- appendLogText(i18n("Manual focusing post filter change is not supported. Run Autofocus process before trying again."));
- abort();
- return;
- }
-
- activeJob->setCurrentFilter(currentFilterPosition);
-
- if (currentFilterPosition != activeJob->getTargetFilter())
- {
- appendLogText(i18n("Changing filter to %1...", FilterPosCombo->itemText(activeJob->getTargetFilter()-1)));
- secondsLabel->setText(i18n("Set filter..."));
-
- if (activeJob->isPreview() == false)
- {
- state = CAPTURE_CHANGING_FILTER;
- emit newStatus(Ekos::CAPTURE_CHANGING_FILTER);
- }
-
- setBusy(true);
-
- }
- }
-
- if (currentCCD->hasCooler() && activeJob->getEnforceTemperature())
- {
- if (activeJob->getCurrentTemperature() != INVALID_TEMPERATURE &&
- fabs(activeJob->getCurrentTemperature() - activeJob->getTargetTemperature()) > Options::maxTemperatureDiff())
- {
- appendLogText(i18n("Setting temperature to %1 C...", activeJob->getTargetTemperature()));
- secondsLabel->setText(i18n("Set %1 C...", activeJob->getTargetTemperature()));
-
- if (activeJob->isPreview() == false)
- {
- state = CAPTURE_SETTING_TEMPERATURE;
- emit newStatus(Ekos::CAPTURE_SETTING_TEMPERATURE);
- }
-
- setBusy(true);
- }
- }
-
- connect(activeJob, SIGNAL(prepareComplete()), this, SLOT(executeJob()));
-
- job->prepareCapture();
-}
-
-void Capture::executeJob()
-{
- activeJob->disconnect(this);
-
- if (activeJob->isPreview())
- seqTotalCount = -1;
- else
- seqTotalCount = activeJob->getCount();
-
- seqDelay = activeJob->getDelay();
-
- seqCurrentCount = activeJob->getCompleted();
-
- if (activeJob->isPreview() == false)
- {
- fullImgCountOUT->setText( QString::number(seqTotalCount));
- currentImgCountOUT->setText(QString::number(seqCurrentCount));
-
- // set the progress info
- imgProgress->setEnabled(true);
- imgProgress->setMaximum(seqTotalCount);
- imgProgress->setValue(seqCurrentCount);
-
- if (currentCCD->getUploadMode() != ISD::CCD::UPLOAD_LOCAL)
- updateSequencePrefix(activeJob->getPrefix(), activeJob->getFITSDir());
- }
-
- // We check if the job is already fully or partially complete by checking how many files of its type exist on the file system unless ignoreJobProgress is set to true
- if (ignoreJobProgress == false && Options::rememberJobProgress() && activeJob->isPreview() == false)
- {
- checkSeqBoundary(activeJob->getFITSDir());
-
- if (seqFileCount > 0)
- {
- // Fully complete
- if (seqFileCount >= seqTotalCount)
- {
- seqCurrentCount=seqTotalCount;
- activeJob->setCompleted(seqCurrentCount);
- imgProgress->setValue(seqCurrentCount);
- processJobCompletion();
- return;
- }
-
- // Partially complete
- seqCurrentCount=seqFileCount;
- activeJob->setCompleted(seqCurrentCount);
- currentImgCountOUT->setText( QString::number(seqCurrentCount));
- imgProgress->setValue(seqCurrentCount);
-
- // Emit progress update
- emit newImage(NULL, activeJob);
- }
- }
-
- // Update button status
- setBusy(true);
-
- useGuideHead = (activeJob->getActiveChip()->getType() == ISD::CCDChip::PRIMARY_CCD) ? false : true;
-
- // Check flat field frame requirements
- if (activeJob->getFrameType() != FRAME_LIGHT && activeJob->isPreview() == false)
- {
- // Make sure we don't have any pre-capture pending jobs for flat frames
- IPState rc = processPreCaptureCalibrationStage();
-
- if (rc == IPS_ALERT)
- return;
- else if (rc == IPS_BUSY)
- {
- secondsLabel->clear();
- QTimer::singleShot(1000, this, SLOT(executeJob()));
- return;
- }
- }
-
- syncGUIToJob(activeJob);
-
- captureImage();
-}
-
-void Capture::setGuideDeviation(double delta_ra, double delta_dec)
-{
- if (guideDeviationCheck->isChecked() == false || activeJob == NULL)
- return;
-
- // If guiding is started after a meridian flip we will start getting guide deviations again
- // if the guide deviations are within our limits, we resume the sequence
- if (meridianFlipStage == MF_GUIDING)
- {
- double deviation_rms = sqrt(delta_ra*delta_ra + delta_dec*delta_dec);
- if (deviation_rms < guideDeviation->value())
- {
- initialHA = getCurrentHA();
- appendLogText(i18n("Post meridian flip calibration completed successfully."));
- resumeSequence();
- // N.B. Set meridian flip stage AFTER resumeSequence() always
- meridianFlipStage = MF_NONE;
- return;
- }
- }
-
- // We don't enforce limit on previews
- if (activeJob->isPreview() || activeJob->getExposeLeft() == 0)
- return;
-
- double deviation_rms = sqrt(delta_ra*delta_ra + delta_dec*delta_dec);
-
- QString deviationText = QString("%1").arg(deviation_rms, 0, 'g', 3);
-
- if (activeJob->getStatus() == SequenceJob::JOB_BUSY)
- {
- if (deviation_rms > guideDeviation->value())
- {
- // Ignore spikes ONCE
- if (spikeDetected == false)
- {
- spikeDetected = true;
- return;
- }
-
- spikeDetected = false;
- deviationDetected = true;
- appendLogText(i18n("Guiding deviation %1 exceeded limit value of %2 arcsecs, aborting exposure.", deviationText, guideDeviation->value()));
- abort();
- }
- return;
- }
-
- if (activeJob->getStatus() == SequenceJob::JOB_ABORTED && deviationDetected)
- {
- if (deviation_rms <= guideDeviation->value())
- {
- if (seqDelay == 0)
- appendLogText(i18n("Guiding deviation %1 is now lower than limit value of %2 arcsecs, resuming exposure.", deviationText, guideDeviation->value()));
- else
- appendLogText(i18n("Guiding deviation %1 is now lower than limit value of %2 arcsecs, resuming exposure in %3 seconds.", deviationText, guideDeviation->value(), seqDelay/1000.0));
-
- activeJob = NULL;
-
- QTimer::singleShot(seqDelay, this, SLOT(start()));
- return;
- }
- }
-}
-
-void Capture::setGuideDither(bool enable)
-{
- guideDither = enable;
-}
-
-void Capture::setFocusStatus(FocusState state)
-{
- focusState = state;
-
- if (focusState > FOCUS_ABORTED)
- return;
-
- if (focusState == FOCUS_COMPLETE)
- {
- autofocusCheck->setEnabled(true);
- HFRPixels->setEnabled(true);
- if (focusHFR > 0 && firstAutoFocus && HFRPixels->value() == 0 && fileHFR == 0)
- {
- firstAutoFocus = false;
- // Add 2.5% to the automatic initial HFR value to allow for minute changes in HFR without need to refocus
- // in case in-sequence-focusing is used.
- HFRPixels->setValue(focusHFR + (focusHFR * 0.025));
- }
- }
-
- if (activeJob && (activeJob->getStatus() == SequenceJob::JOB_ABORTED || activeJob->getStatus() == SequenceJob::JOB_IDLE))
- {
- if (focusState == FOCUS_COMPLETE)
- {
- HFRPixels->setValue(focusHFR+ (focusHFR * 0.025));
- appendLogText(i18n("Focus complete."));
- }
- else
- {
- appendLogText(i18n("Autofocus failed. Aborting exposure..."));
- secondsLabel->setText("");
- abort();
- }
-
- activeJob->setFilterPostFocusReady(focusState == FOCUS_COMPLETE);
- return;
- }
-
- if (isAutoFocus && activeJob && activeJob->getStatus() == SequenceJob::JOB_BUSY)
- {
- if (focusState == FOCUS_COMPLETE)
- {
- appendLogText(i18n("Focus complete."));
- startNextExposure();
- }
- else
- {
- appendLogText(i18n("Autofocus failed. Aborting exposure..."));
- secondsLabel->setText("");
- abort();
- }
- }
-}
-
-void Capture::setTelescope(ISD::GDInterface *newTelescope)
-{
- currentTelescope = static_cast<ISD::Telescope*> (newTelescope);
-
- connect(currentTelescope, SIGNAL(numberUpdated(INumberVectorProperty*)), this, SLOT(processTelescopeNumber(INumberVectorProperty*)), Qt::UniqueConnection);
-
- meridianCheck->setEnabled(true);
- meridianHours->setEnabled(true);
-
- syncTelescopeInfo();
-}
-
-void Capture::syncTelescopeInfo()
-{
- if (currentCCD && currentTelescope && currentTelescope->isConnected())
- {
- parkCheck->setEnabled(currentTelescope->canPark());
-
- ITextVectorProperty *activeDevices = currentCCD->getBaseDevice()->getText("ACTIVE_DEVICES");
- if (activeDevices)
- {
- IText *activeTelescope = IUFindText(activeDevices, "ACTIVE_TELESCOPE");
- if (activeTelescope)
- {
- IUSaveText(activeTelescope, currentTelescope->getDeviceName());
-
- currentCCD->getDriverInfo()->getClientManager()->sendNewText(activeDevices);
- }
- }
- }
-}
-
-void Capture::saveFITSDirectory()
-{
- QString dir = QFileDialog::getExistingDirectory(KStars::Instance(), i18n("FITS Save Directory"), dirPath.toLocalFile());
-
- if (dir.isEmpty())
- return;
-
- fitsDir->setText(dir);
-
-}
-
-void Capture::loadSequenceQueue()
-{
- QUrl fileURL = QFileDialog::getOpenFileUrl(KStars::Instance(), i18n("Open Ekos Sequence Queue"), dirPath, "Ekos Sequence Queue (*.esq)");
- if (fileURL.isEmpty())
- return;
-
- if (fileURL.isValid() == false)
- {
- QString message = i18n( "Invalid URL: %1", fileURL.toLocalFile() );
- KMessageBox::sorry( 0, message, i18n( "Invalid URL" ) );
- return;
- }
-
- dirPath = QUrl(fileURL.url(QUrl::RemoveFilename));
-
- loadSequenceQueue(fileURL.toLocalFile());
-
-}
-
-bool Capture::loadSequenceQueue(const QString &fileURL)
-{
- QFile sFile;
- sFile.setFileName(fileURL);
-
- if ( !sFile.open( QIODevice::ReadOnly))
- {
- QString message = i18n( "Unable to open file %1", fileURL);
- KMessageBox::sorry( 0, message, i18n( "Could Not Open File" ) );
- return false;
- }
-
- //QTextStream instream(&sFile);
-
- qDeleteAll(jobs);
- jobs.clear();
- while (queueTable->rowCount() > 0)
- queueTable->removeRow(0);
-
- LilXML *xmlParser = newLilXML();
- char errmsg[MAXRBUF];
- XMLEle *root = NULL;
- XMLEle *ep;
- char c;
-
- while ( sFile.getChar(&c))
- {
- root = readXMLEle(xmlParser, c, errmsg);
-
- if (root)
- {
- for (ep = nextXMLEle(root, 1) ; ep != NULL ; ep = nextXMLEle(root, 0))
- {
- if (!strcmp(tagXMLEle(ep), "GuideDeviation"))
- {
- if (!strcmp(findXMLAttValu(ep, "enabled"), "true"))
- {
- guideDeviationCheck->setChecked(true);
- guideDeviation->setValue(atof(pcdataXMLEle(ep)));
- }
- else
- guideDeviationCheck->setChecked(false);
-
- }
- else if (!strcmp(tagXMLEle(ep), "Autofocus"))
- {
- if (!strcmp(findXMLAttValu(ep, "enabled"), "true"))
- {
- autofocusCheck->setChecked(true);
- float HFRValue = atof(pcdataXMLEle(ep));
- if (HFRValue > 0)
- {
- fileHFR = HFRValue;
- HFRPixels->setValue(HFRValue);
- }
- else
- fileHFR=0;
- }
- else
- autofocusCheck->setChecked(false);
-
- }
- else if (!strcmp(tagXMLEle(ep), "MeridianFlip"))
- {
- if (!strcmp(findXMLAttValu(ep, "enabled"), "true"))
- {
- meridianCheck->setChecked(true);
- meridianHours->setValue(atof(pcdataXMLEle(ep)));
- }
- else
- meridianCheck->setChecked(false);
-
- }
- else if (!strcmp(tagXMLEle(ep), "Park"))
- {
- if (!strcmp(findXMLAttValu(ep, "enabled"), "true"))
- parkCheck->setChecked(true);
- else
- parkCheck->setChecked(false);
-
- }
- else
- {
- processJobInfo(ep);
- }
-
- }
- delXMLEle(root);
- }
- else if (errmsg[0])
- {
- appendLogText(QString(errmsg));
- delLilXML(xmlParser);
- return false;
- }
- }
-
- sequenceURL = QUrl::fromLocalFile(fileURL);
- mDirty = false;
- delLilXML(xmlParser);
-
- if (Options::rememberJobProgress())
- ignoreJobProgress = false;
-
- return true;
-
-}
-
-bool Capture::processJobInfo(XMLEle *root)
-{
-
- XMLEle *ep;
- XMLEle *subEP;
-
- for (ep = nextXMLEle(root, 1) ; ep != NULL ; ep = nextXMLEle(root, 0))
- {
- if (!strcmp(tagXMLEle(ep), "Exposure"))
- exposureIN->setValue(atof(pcdataXMLEle(ep)));
- else if (!strcmp(tagXMLEle(ep), "Binning"))
- {
- subEP = findXMLEle(ep, "X");
- if (subEP)
- binXIN->setValue(atoi(pcdataXMLEle(subEP)));
- subEP = findXMLEle(ep, "Y");
- if (subEP)
- binYIN->setValue(atoi(pcdataXMLEle(subEP)));
- }
- else if (!strcmp(tagXMLEle(ep), "Frame"))
- {
- subEP = findXMLEle(ep, "X");
- if (subEP)
- frameXIN->setValue(atoi(pcdataXMLEle(subEP)));
- subEP = findXMLEle(ep, "Y");
- if (subEP)
- frameYIN->setValue(atoi(pcdataXMLEle(subEP)));
- subEP = findXMLEle(ep, "W");
- if (subEP)
- frameWIN->setValue(atoi(pcdataXMLEle(subEP)));
- subEP = findXMLEle(ep, "H");
- if (subEP)
- frameHIN->setValue(atoi(pcdataXMLEle(subEP)));
- }
- else if (!strcmp(tagXMLEle(ep), "Temperature"))
- {
- if (temperatureIN->isEnabled())
- temperatureIN->setValue(atof(pcdataXMLEle(ep)));
-
- // If force attribute exist, we change temperatureCheck, otherwise do nothing.
- if (!strcmp(findXMLAttValu(ep, "force"), "true"))
- temperatureCheck->setChecked(true);
- else if (!strcmp(findXMLAttValu(ep, "force"), "false"))
- temperatureCheck->setChecked(false);
-
- }
- else if (!strcmp(tagXMLEle(ep), "Filter"))
- {
- FilterPosCombo->setCurrentIndex(atoi(pcdataXMLEle(ep))-1);
- }
- else if (!strcmp(tagXMLEle(ep), "Type"))
- {
- frameTypeCombo->setCurrentText(pcdataXMLEle(ep));
- }
- else if (!strcmp(tagXMLEle(ep), "Prefix"))
- {
- subEP = findXMLEle(ep, "RawPrefix");
- if (subEP)
- prefixIN->setText(pcdataXMLEle(subEP));
- subEP = findXMLEle(ep, "FilterEnabled");
- if (subEP)
- filterCheck->setChecked( !strcmp("1", pcdataXMLEle(subEP)));
- subEP = findXMLEle(ep, "ExpEnabled");
- if (subEP)
- expDurationCheck->setChecked( !strcmp("1", pcdataXMLEle(subEP)));
- subEP = findXMLEle(ep, "TimeStampEnabled");
- if (subEP)
- ISOCheck->setChecked( !strcmp("1", pcdataXMLEle(subEP)));
- }
- else if (!strcmp(tagXMLEle(ep), "Count"))
- {
- countIN->setValue(atoi(pcdataXMLEle(ep)));
- }
- else if (!strcmp(tagXMLEle(ep), "Delay"))
- {
- delayIN->setValue(atoi(pcdataXMLEle(ep)));
- }
- else if (!strcmp(tagXMLEle(ep), "FITSDirectory"))
- {
- fitsDir->setText(pcdataXMLEle(ep));
- }
- else if (!strcmp(tagXMLEle(ep), "ISOIndex"))
- {
- if (ISOCombo->isEnabled())
- ISOCombo->setCurrentIndex(atoi(pcdataXMLEle(ep)));
- }
- else if (!strcmp(tagXMLEle(ep), "Calibration"))
- {
- subEP = findXMLEle(ep, "FlatSource");
- if (subEP)
- {
- XMLEle *typeEP = findXMLEle(subEP, "Type");
- if (typeEP)
- {
- if (!strcmp(pcdataXMLEle(typeEP), "Manual"))
- flatFieldSource = SOURCE_MANUAL;
- else if (!strcmp(pcdataXMLEle(typeEP), "FlatCap"))
- flatFieldSource = SOURCE_FLATCAP;
- else if (!strcmp(pcdataXMLEle(typeEP), "DarkCap"))
- flatFieldSource = SOURCE_DARKCAP;
- else if (!strcmp(pcdataXMLEle(typeEP), "Wall"))
- {
- XMLEle *azEP=NULL, *altEP=NULL;
- azEP = findXMLEle(subEP, "Az");
- altEP = findXMLEle(subEP, "Alt");
- if (azEP && altEP)
- {
- flatFieldSource =SOURCE_WALL;
- wallCoord.setAz(atof(pcdataXMLEle(azEP)));
- wallCoord.setAlt(atof(pcdataXMLEle(altEP)));
- }
- }
- else
- flatFieldSource = SOURCE_DAWN_DUSK;
-
- }
- }
-
- subEP = findXMLEle(ep, "FlatDuration");
- if (subEP)
- {
- XMLEle *typeEP = findXMLEle(subEP, "Type");
- if (typeEP)
- {
- if (!strcmp(pcdataXMLEle(typeEP), "Manual"))
- flatFieldDuration = DURATION_MANUAL;
- }
-
- XMLEle *aduEP= findXMLEle(subEP, "Value");
- if (aduEP)
- {
- flatFieldDuration = DURATION_ADU;
- targetADU = atof(pcdataXMLEle(aduEP));
- }
- }
-
- subEP = findXMLEle(ep, "PreMountPark");
- if (subEP)
- {
- if (!strcmp(pcdataXMLEle(subEP), "True"))
- preMountPark = true;
- else
- preMountPark = false;
- }
-
- subEP = findXMLEle(ep, "PreDomePark");
- if (subEP)
- {
- if (!strcmp(pcdataXMLEle(subEP), "True"))
- preDomePark = true;
- else
- preDomePark = false;
- }
- }
- }
-
- addJob(false);
-
- return true;
-}
-
-void Capture::saveSequenceQueue()
-{
- QUrl backupCurrent = sequenceURL;
-
- if (sequenceURL.toLocalFile().startsWith("/tmp/") || sequenceURL.toLocalFile().contains("/Temp"))
- sequenceURL.clear();
-
- // If no changes made, return.
- if( mDirty == false && !sequenceURL.isEmpty())
- return;
-
- if (sequenceURL.isEmpty())
- {
- sequenceURL = QFileDialog::getSaveFileUrl(KStars::Instance(), i18n("Save Ekos Sequence Queue"), dirPath, "Ekos Sequence Queue (*.esq)");
- // if user presses cancel
- if (sequenceURL.isEmpty())
- {
- sequenceURL = backupCurrent;
- return;
- }
-
- dirPath = QUrl(sequenceURL.url(QUrl::RemoveFilename));
-
- if (sequenceURL.toLocalFile().endsWith(".esq") == false)
- sequenceURL.setPath(sequenceURL.toLocalFile() + ".esq");
-
- if (QFile::exists(sequenceURL.toLocalFile()))
- {
- int r = KMessageBox::warningContinueCancel(0,
- i18n( "A file named \"%1\" already exists. "
- "Overwrite it?", sequenceURL.fileName() ),
- i18n( "Overwrite File?" ),
- KGuiItem(i18n( "&Overwrite" )) );
- if(r==KMessageBox::Cancel) return;
- }
- }
-
- if ( sequenceURL.isValid() )
- {
- if ( (saveSequenceQueue(sequenceURL.toLocalFile())) == false)
- {
- KMessageBox::error(KStars::Instance(), i18n("Failed to save sequence queue"), i18n("Save"));
- return;
- }
-
- mDirty = false;
-
- } else
- {
- QString message = i18n( "Invalid URL: %1", sequenceURL.url() );
- KMessageBox::sorry(KStars::Instance(), message, i18n( "Invalid URL" ) );
- }
-
-}
-
-void Capture::saveSequenceQueueAs()
-{
- sequenceURL.clear();
- saveSequenceQueue();
-}
-
-bool Capture::saveSequenceQueue(const QString &path)
-{
- QFile file;
- QString rawPrefix;
- bool filterEnabled, expEnabled, tsEnabled;
-
- file.setFileName(path);
-
- if ( !file.open( QIODevice::WriteOnly))
- {
- QString message = i18n( "Unable to write to file %1", path);
- KMessageBox::sorry( 0, message, i18n( "Could Not Open File" ) );
- return false;
- }
-
- QTextStream outstream(&file);
-
- outstream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
- outstream << "<SequenceQueue version='1.3'>" << endl;
- outstream << "<GuideDeviation enabled='" << (guideDeviationCheck->isChecked() ? "true" : "false") << "'>" << guideDeviation->value() << "</GuideDeviation>" << endl;
- outstream << "<Autofocus enabled='" << (autofocusCheck->isChecked() ? "true" : "false") << "'>" << HFRPixels->value() << "</Autofocus>" << endl;
- outstream << "<MeridianFlip enabled='" << (meridianCheck->isChecked() ? "true" : "false") << "'>" << meridianHours->value() << "</MeridianFlip>" << endl;
- outstream << "<Park enabled='" << (parkCheck->isChecked() ? "true" : "false") << "'></Park>" << endl;
- foreach(SequenceJob *job, jobs)
- {
- job->getPrefixSettings(rawPrefix, filterEnabled, expEnabled, tsEnabled);
-
- outstream << "<Job>" << endl;
-
- outstream << "<Exposure>" << job->getExposure() << "</Exposure>" << endl;
- outstream << "<Binning>" << endl;
- outstream << "<X>"<< job->getXBin() << "</X>" << endl;
- outstream << "<Y>"<< job->getXBin() << "</Y>" << endl;
- outstream << "</Binning>" << endl;
- outstream << "<Frame>" << endl;
- outstream << "<X>" << job->getSubX() << "</X>" << endl;
- outstream << "<Y>" << job->getSubY() << "</Y>" << endl;
- outstream << "<W>" << job->getSubW() << "</W>" << endl;
- outstream << "<H>" << job->getSubH() << "</H>" << endl;
- outstream << "</Frame>" << endl;
- if (job->getTargetTemperature() != INVALID_TEMPERATURE)
- outstream << "<Temperature force='" << (job->getEnforceTemperature() ? "true":"false") << "'>" << job->getTargetTemperature() << "</Temperature>" << endl;
- if (job->getTargetFilter() >= 0)
- outstream << "<Filter>" << job->getTargetFilter() << "</Filter>" << endl;
- outstream << "<Type>" << frameTypeCombo->itemText(job->getFrameType()) << "</Type>" << endl;
- outstream << "<Prefix>" << endl;
- //outstream << "<CompletePrefix>" << job->getPrefix() << "</CompletePrefix>" << endl;
- outstream << "<RawPrefix>" << rawPrefix << "</RawPrefix>" << endl;
- outstream << "<FilterEnabled>" << (filterEnabled ? 1 : 0) << "</FilterEnabled>" << endl;
- outstream << "<ExpEnabled>" << (expEnabled ? 1 : 0) << "</ExpEnabled>" << endl;
- outstream << "<TimeStampEnabled>" << (tsEnabled ? 1 : 0) << "</TimeStampEnabled>" << endl;
- outstream << "</Prefix>" << endl;
- outstream << "<Count>" << job->getCount() << "</Count>" << endl;
- // ms to seconds
- outstream << "<Delay>" << job->getDelay()/1000 << "</Delay>" << endl;
- QString rootDir = job->getRootFITSDir();
- outstream << "<FITSDirectory>" << rootDir << "</FITSDirectory>" << endl;
- if (job->getISOIndex() != -1)
- outstream << "<ISOIndex>" << (job->getISOIndex()) << "</ISOIndex>" << endl;
-
- outstream << "<Calibration>" << endl;
- outstream << "<FlatSource>" << endl;
- if (job->getFlatFieldSource() == SOURCE_MANUAL)
- outstream << "<Type>Manual</Type>" << endl;
- else if (job->getFlatFieldSource() == SOURCE_FLATCAP)
- outstream << "<Type>FlatCap</Type>" << endl;
- else if (job->getFlatFieldSource() == SOURCE_DARKCAP)
- outstream << "<Type>DarkCap</Type>" << endl;
- else if (job->getFlatFieldSource() == SOURCE_WALL)
- {
- outstream << "<Type>Wall</Type>" << endl;
- outstream << "<Az>" << job->getWallCoord().az().Degrees() << "</Az>" << endl;
- outstream << "<Alt>" << job->getWallCoord().alt().Degrees() << "</Alt>" << endl;
- }
- else
- outstream << "<Type>DawnDust</Type>" << endl;
- outstream << "</FlatSource>" << endl;
-
- outstream << "<FlatDuration>" << endl;
- if (job->getFlatFieldDuration() == DURATION_MANUAL)
- outstream << "<Type>Manual</Type>" << endl;
- else
- {
- outstream << "<Type>ADU</Type>" << endl;
- outstream << "<Value>" << job->getTargetADU() << "</Value>" << endl;
- }
- outstream << "</FlatDuration>" << endl;
-
- outstream << "<PreMountPark>" << (job->isPreMountPark() ? "True" : "False") << "</PreMountPark>" << endl;
- outstream << "<PreDomePark>" << (job->isPreDomePark() ? "True" : "False") << "</PreDomePark>" << endl;
- outstream << "</Calibration>" << endl;
-
- outstream << "</Job>" << endl;
- }
-
- outstream << "</SequenceQueue>" << endl;
-
- appendLogText(i18n("Sequence queue saved to %1", path));
- file.close();
- return true;
-}
-
-void Capture::resetJobs()
-{
- if (KMessageBox::warningContinueCancel(NULL, i18n("Are you sure you want to reset status of all jobs?"),
- i18n("Reset job status"), KStandardGuiItem::cont(), KStandardGuiItem::cancel(),
- "reset_job_status_warning") !=KMessageBox::Continue)
- return;
-
- foreach(SequenceJob *job, jobs)
- job->resetStatus();
-
- stop();
-
- // Reste active job pointer
- activeJob = NULL;
-
- ignoreJobProgress=true;
-}
-
-void Capture::ignoreSequenceHistory()
-{
- ignoreJobProgress=true;
-}
-
-void Capture::syncGUIToJob(SequenceJob *job)
-{
- QString rawPrefix;
- bool filterEnabled, expEnabled, tsEnabled;
-
- job->getPrefixSettings(rawPrefix, filterEnabled, expEnabled, tsEnabled);
-
- exposureIN->setValue(job->getExposure());
- binXIN->setValue(job->getXBin());
- binYIN->setValue(job->getYBin());
- frameXIN->setValue(job->getSubX());
- frameYIN->setValue(job->getSubY());
- frameWIN->setValue(job->getSubW());
- frameHIN->setValue(job->getSubH());
- FilterPosCombo->setCurrentIndex(job->getTargetFilter()-1);
- frameTypeCombo->setCurrentIndex(job->getFrameType());
- prefixIN->setText(rawPrefix);
- filterCheck->setChecked(filterEnabled);
- expDurationCheck->setChecked(expEnabled);
- ISOCheck->setChecked(tsEnabled);
- countIN->setValue(job->getCount());
- delayIN->setValue(job->getDelay()/1000);
-
- // Temperature Options
- temperatureCheck->setChecked(job->getEnforceTemperature());
-
- // Flat field options
- calibrationB->setEnabled(job->getFrameType() != FRAME_LIGHT);
- flatFieldDuration = job->getFlatFieldDuration();
- flatFieldSource = job->getFlatFieldSource();
- targetADU = job->getTargetADU();
- wallCoord = job->getWallCoord();
- preMountPark = job->isPreMountPark();
- preDomePark = job->isPreDomePark();
-
- fitsDir->setText(job->getRootFITSDir());
-
- if (ISOCombo->isEnabled())
- ISOCombo->setCurrentIndex(job->getISOIndex());
-}
-
-void Capture::editJob(QModelIndex i)
-{
- SequenceJob *job = jobs.at(i.row());
- if (job == NULL)
- return;
-
-
- syncGUIToJob(job);
-
- appendLogText(i18n("Editing job #%1...", i.row()+1));
-
- addToQueueB->setIcon(QIcon::fromTheme("dialog-ok-apply"));
- addToQueueB->setToolTip(i18n("Apply job changes."));
- removeFromQueueB->setToolTip(i18n("Cancel job changes."));
-
- jobUnderEdit = true;
-
-}
-
-void Capture::resetJobEdit()
-{
- if (jobUnderEdit)
- appendLogText(i18n("Editing job canceled."));
-
- jobUnderEdit = false;
- addToQueueB->setIcon(QIcon::fromTheme("list-add"));
-
- addToQueueB->setToolTip(i18n("Add job to sequence queue"));
- removeFromQueueB->setToolTip(i18n("Remove job from sequence queue"));
-}
-
-void Capture::constructPrefix(QString &imagePrefix)
-{
-
- if (imagePrefix.isEmpty() == false)
- imagePrefix += '_';
-
- imagePrefix += frameTypeCombo->currentText();
-
- if (filterCheck->isChecked() && FilterPosCombo->currentText().isEmpty() == false &&
- frameTypeCombo->currentText().compare("Bias", Qt::CaseInsensitive) &&
- frameTypeCombo->currentText().compare("Dark", Qt::CaseInsensitive))
- {
- //if (imagePrefix.isEmpty() == false || frameTypeCheck->isChecked())
- imagePrefix += '_';
-
- imagePrefix += FilterPosCombo->currentText();
- }
- if (expDurationCheck->isChecked())
- {
- //if (imagePrefix.isEmpty() == false || frameTypeCheck->isChecked())
- imagePrefix += '_';
-
- imagePrefix += QString::number(exposureIN->value(), 'd', 0) + QString("_secs");
- }
-}
-
-double Capture::getProgressPercentage()
-{
- int totalImageCount=0;
- int totalImageCompleted=0;
-
- foreach(SequenceJob *job, jobs)
- {
- totalImageCount += job->getCount();
- totalImageCompleted += job->getCompleted();
- }
-
- if (totalImageCount != 0)
- return ( ( (double) totalImageCompleted / totalImageCount) * 100.0);
- else
- return -1;
-}
-
-int Capture::getActiveJobID()
-{
- if (activeJob == NULL)
- return -1;
-
- for (int i=0; i < jobs.count(); i++)
- {
- if (activeJob == jobs[i])
- return i;
- }
-
- return -1;
-}
-
-QString Capture::getJobState(int id)
-{
- if (id < jobs.count())
- {
- SequenceJob *job = jobs.at(id);
- return job->getStatusString();
- }
-
- return QString();
-}
-
-int Capture::getJobImageProgress(int id)
-{
- if (id < jobs.count())
- {
- SequenceJob *job = jobs.at(id);
- return job->getCompleted();
- }
-
- return -1;
-}
-
-int Capture::getJobImageCount(int id)
-{
- if (id < jobs.count())
- {
- SequenceJob *job = jobs.at(id);
- return job->getCount();
- }
-
- return -1;
-}
-
-double Capture::getJobExposureProgress(int id)
-{
- if (id < jobs.count())
- {
- SequenceJob *job = jobs.at(id);
- return job->getExposeLeft();
- }
-
- return -1;
-}
-
-double Capture::getJobExposureDuration(int id)
-{
- if (id < jobs.count())
- {
- SequenceJob *job = jobs.at(id);
- return job->getExposure();
- }
-
- return -1;
-}
-
-int Capture::getJobRemainingTime(SequenceJob *job)
-{
- int remaining=0;
-
- if (job->getStatus() == SequenceJob::JOB_BUSY)
- remaining += (job->getExposure() + job->getDelay()/1000) * (job->getCount() - job->getCompleted()) + job->getExposeLeft();
- else
- remaining += (job->getExposure() + job->getDelay()/1000) * (job->getCount() - job->getCompleted());
-
- return remaining;
-}
-
-int Capture::getOverallRemainingTime()
-{
- double remaining=0;
-
- foreach(SequenceJob *job, jobs)
- remaining += getJobRemainingTime(job);
-
- return remaining;
-}
-
-int Capture::getActiveJobRemainingTime()
-{
- if (activeJob == NULL)
- return -1;
-
- return getJobRemainingTime(activeJob);
-}
-
-void Capture::setMaximumGuidingDeviaiton(bool enable, double value)
-{
- if (guideDeviationCheck->isEnabled())
- {
- guideDeviationCheck->setChecked(enable);
- if (enable)
- guideDeviation->setValue(value);
- }
-
-}
-
-void Capture::setInSequenceFocus(bool enable, double HFR)
-{
- if (autofocusCheck->isEnabled())
- {
- autofocusCheck->setChecked(enable);
- if (enable)
- HFRPixels->setValue(HFR);
- }
-}
-
-void Capture::setParkOnComplete(bool enable)
-{
- if (parkCheck->isEnabled())
- parkCheck->setChecked(enable);
-}
-
-void Capture::setTemperature()
-{
- if (currentCCD)
- currentCCD->setTemperature(temperatureIN->value());
-}
-
-void Capture::clearSequenceQueue()
-{
- activeJob=NULL;
- targetName = QString();
- stop();
- while (queueTable->rowCount() > 0)
- queueTable->removeRow(0);
- jobs.clear();
- qDeleteAll(jobs);
- ignoreJobProgress = true;
-
-}
-
-QString Capture::getSequenceQueueStatus()
-{
- if (jobs.count() == 0)
- return "Invalid";
-
- if (isBusy)
- return "Running";
-
- int idle=0, error=0, complete=0, aborted=0,running=0;
-
- foreach(SequenceJob* job, jobs)
- {
- switch (job->getStatus())
- {
- case SequenceJob::JOB_ABORTED:
- aborted++;
- break;
- case SequenceJob::JOB_BUSY:
- running++;
- break;
- case SequenceJob::JOB_DONE:
- complete++;
- break;
- case SequenceJob::JOB_ERROR:
- error++;
- break;
- case SequenceJob::JOB_IDLE:
- idle++;
- break;
- }
- }
-
- if (error > 0)
- return "Error";
-
- if (aborted > 0)
- {
- if (guideState == GUIDE_GUIDING && deviationDetected)
- return "Suspended";
- else
- return "Aborted";
- }
-
- if (running > 0)
- return "Running";
-
- if (idle == jobs.count())
- return "Idle";
-
- if (complete == jobs.count())
- return "Complete";
-
- return "Invalid";
-}
-
-void Capture::processTelescopeNumber(INumberVectorProperty *nvp)
-{
- // If it is not ours, return.
- if (strcmp(nvp->device, currentTelescope->getDeviceName()) || strcmp(nvp->name, "EQUATORIAL_EOD_COORD"))
- return;
-
- switch (meridianFlipStage)
- {
- case MF_NONE:
- break;
- case MF_INITIATED:
- {
- if (nvp->s == IPS_BUSY)
- meridianFlipStage = MF_FLIPPING;
- }
- break;
-
- case MF_FLIPPING:
- {
- double ra, dec;
- currentTelescope->getEqCoords(&ra, &dec);
- double diffRA = initialRA - ra;
- if (fabs(diffRA) > MF_RA_DIFF_LIMIT || nvp->s == IPS_OK)
- meridianFlipStage = MF_SLEWING;
- }
- break;
-
- case MF_SLEWING:
-
- if (nvp->s != IPS_OK)
- break;
-
- // If dome is syncing, wait until it stops
- if (dome && dome->isMoving())
- break;
-
- // We are at a new initialHA
- initialHA= getCurrentHA();
-
- appendLogText(i18n("Telescope completed the meridian flip."));
-
- if (resumeAlignmentAfterFlip == true)
- {
- appendLogText(i18n("Performing post flip re-alignment..."));
- secondsLabel->setText(i18n("Aligning..."));
-
- state = CAPTURE_ALIGNING;
- emit newStatus(Ekos::CAPTURE_ALIGNING);
-
- meridianFlipStage = MF_ALIGNING;
- //QTimer::singleShot(Options::settlingTime(), [this]() {emit meridialFlipTracked();});
- //emit meridialFlipTracked();
- return;
- }
-
- checkGuidingAfterFlip();
- break;
-
- default:
- break;
- }
-
-}
-
-void Capture::checkGuidingAfterFlip()
-{
- // If we're not autoguiding then we're done
- if (resumeGuidingAfterFlip == false)
- {
- resumeSequence();
- // N.B. Set meridian flip stage AFTER resumeSequence() always
- meridianFlipStage = MF_NONE;
- }
- else
- {
- appendLogText(i18n("Performing post flip re-calibration and guiding..."));
- secondsLabel->setText(i18n("Calibrating..."));
-
- state = CAPTURE_CALIBRATING;
- emit newStatus(Ekos::CAPTURE_CALIBRATING);
-
- meridianFlipStage = MF_GUIDING;
- emit meridianFlipCompleted();
- }
-}
-
-double Capture::getCurrentHA()
-{
- double currentRA, currentDEC;
-
- if (currentTelescope == NULL)
- return INVALID_HA;
-
- if (currentTelescope->getEqCoords(&currentRA, &currentDEC) == false)
- {
- appendLogText(i18n("Failed to retrieve telescope coordinates. Unable to calculate telescope's hour angle."));
- return INVALID_HA;
- }
-
- dms lst = KStarsData::Instance()->geo()->GSTtoLST(KStarsData::Instance()->clock()->utc().gst());
-
- dms ha( lst.Degrees() - currentRA*15.0 );
-
- double HA = ha.Hours();
-
- if (HA > 12)
- HA -= 24;
-
- return HA;
-}
-
-bool Capture::checkMeridianFlip()
-{
-
- if (meridianCheck->isEnabled() == false || meridianCheck->isChecked() == false || initialHA > 0)
- return false;
-
-
- double currentHA = getCurrentHA();
-
- //appendLogText(i18n("Current hour angle %1", currentHA));
-
- if (currentHA == INVALID_HA)
- return false;
-
- if (currentHA > meridianHours->value())
- {
- //NOTE: DO NOT make the follow sentence PLURAL as the value is in double
- appendLogText(i18n("Current hour angle %1 hours exceeds meridian flip limit of %2 hours. Auto meridian flip is initiated.", QString::number(currentHA, 'f', 2), meridianHours->value()));
- meridianFlipStage = MF_INITIATED;
-
- // Suspend guiding first before commanding a meridian flip
- //if (isAutoGuiding && currentCCD->getChip(ISD::CCDChip::GUIDE_CCD) == guideChip)
-// emit suspendGuiding(false);
-
- // If we are autoguiding, we should resume autoguiding after flip
- resumeGuidingAfterFlip = (guideState == GUIDE_GUIDING);
-
- if ((guideState == GUIDE_GUIDING) || isAutoFocus)
- emit meridianFlipStarted();
-
- double dec;
- currentTelescope->getEqCoords(&initialRA, &dec);
- currentTelescope->Slew(initialRA,dec);
- secondsLabel->setText(i18n("Meridian Flip..."));
-
- state = CAPTURE_MERIDIAN_FLIP;
- emit newStatus(Ekos::CAPTURE_MERIDIAN_FLIP);
-
- QTimer::singleShot(MF_TIMER_TIMEOUT, this, SLOT(checkMeridianFlipTimeout()));
- return true;
- }
-
- return false;
-}
-
-void Capture::checkMeridianFlipTimeout()
-{
- if (meridianFlipStage == MF_NONE)
- return;
-
- if (meridianFlipStage < MF_ALIGNING)
- {
- appendLogText(i18n("Telescope meridian flip timed out."));
- abort();
- }
-}
-
-void Capture::setAlignStatus(AlignState state)
-{
- alignState = state;
-
- resumeAlignmentAfterFlip = true;
-
- switch (state)
- {
- case ALIGN_COMPLETE:
- if (meridianFlipStage == MF_ALIGNING)
- {
- appendLogText(i18n("Post flip re-alignment completed successfully."));
- checkGuidingAfterFlip();
- }
- break;
-
- case ALIGN_FAILED:
- // TODO run it 3 times before giving up
- if (meridianFlipStage == MF_ALIGNING)
- {
- appendLogText(i18n("Post-flip alignment failed."));
- abort();
- }
- break;
-
- default:
- break;
-
- }
-}
-
-void Capture::setGuideStatus(GuideState state)
-{
- switch (state)
- {
-
- case GUIDE_IDLE:
- // If Autoguiding was started before and now stopped, let's abort (unless we're doing a meridian flip)
- if (guideState == GUIDE_GUIDING && meridianFlipStage == MF_NONE && activeJob && activeJob->getStatus() == SequenceJob::JOB_BUSY)
- {
- appendLogText(i18n("Autoguiding stopped. Aborting..."));
- abort();
- }
- //isAutoGuiding = false;
- break;
-
- case GUIDE_GUIDING:
- break;
- //isAutoGuiding = true;
-
- case GUIDE_CALIBRATION_SUCESS:
- guideDeviationCheck->setEnabled(true);
- guideDeviation->setEnabled(true);
- break;
-
- case GUIDE_CALIBRATION_ERROR:
- case GUIDE_ABORTED:
- // TODO try restarting calibration a couple of times before giving up
- if (meridianFlipStage == MF_GUIDING)
- {
- appendLogText(i18n("Post meridian flip calibration error. Aborting..."));
- abort();
- }
- break;
-
- case GUIDE_DITHERING_SUCCESS:
- resumeCapture();
- break;
-
- case GUIDE_DITHERING_ERROR:
- abort();
- break;
-
- default:
- break;
- }
-
- guideState = state;
-}
-
-void Capture::checkFrameType(int index)
-{
- if (index == FRAME_LIGHT)
- calibrationB->setEnabled(false);
- else
- calibrationB->setEnabled(true);
-}
-
-double Capture::setCurrentADU(double value)
-{
- double nextExposure = 0;
-
- /*if (ExpRaw1 == -1)
- ExpRaw1 = activeJob->getExposure();
- else if (ExpRaw2 == -1)
- ExpRaw2 = activeJob->getExposure();
- else
- {
- ExpRaw1 = ExpRaw2;
- ExpRaw2 = activeJob->getExposure();
- }
-
- if (ADURaw1 == -1)
- ADURaw1 = value;
- else if (ADURaw2 == -1)
- ADURaw2 = value;
- else
- {
- ADURaw1 = ADURaw2;
- ADURaw2 = value;
- }
-
- qDebug() << "Exposure #1 (" << ExpRaw1 << "," << ADURaw1 << ") Exspoure #2 (" << ExpRaw2 << "," << ADURaw2 << ")";
-
- // If we don't have the 2nd point, let's take another exposure with value relative to what we have now
- if (ADURaw2 == -1 || ExpRaw2 == -1 || (ADURaw1 == ADURaw2))
- {
- if (value < activeJob->getTargetADU())
- nextExposure = activeJob->getExposure()*1.5;
- else
- nextExposure = activeJob->getExposure()*.75;
-
- qDebug() << "Next Exposure: " << nextExposure;
-
- return nextExposure;
- }
-
- if (fabs(ADURaw2 - ADURaw1) < 0.01)
- ADUSlope=1e-6;
- else
- ADUSlope = (ExpRaw2 - ExpRaw1) / (ADURaw2 - ADURaw1);
-
- qDebug() << "ADU Slope: " << ADUSlope;
-
- nextExposure = ADUSlope * (activeJob->getTargetADU() - ADURaw2) + ExpRaw2;
-
- qDebug() << "Next Exposure: " << nextExposure;
-
- return nextExposure;*/
-
- double a=0,b=0;
-
- ExpRaw.append(activeJob->getExposure());
- ADURaw.append(value);
-
- llsq(ExpRaw, ADURaw, a, b);
-
- if (a == 0)
- {
- if (value < activeJob->getTargetADU())
- nextExposure = activeJob->getExposure()*1.5;
- else
- nextExposure = activeJob->getExposure()*.75;
-
- qDebug() << "Next Exposure: " << nextExposure;
-
- return nextExposure;
- }
-
- nextExposure = (activeJob->getTargetADU() - b) / a;
-
- qDebug() << "Next Exposure: " << nextExposure;
-
- return nextExposure;
-
-}
-
-// Based on John Burkardt LLSQ (LGPL)
-void Capture::llsq (QList<double> x, QList<double> y, double &a, double &b)
-{
- double bot;
- int i;
- double top;
- double xbar;
- double ybar;
- int n = x.count();
-//
-// Special case.
-//
- if ( n == 1 )
- {
- a = 0.0;
- b = y[0];
- return;
- }
-//
-// Average X and Y.
-//
- xbar = 0.0;
- ybar = 0.0;
- for ( i = 0; i < n; i++ )
- {
- xbar = xbar + x[i];
- ybar = ybar + y[i];
- }
- xbar = xbar / ( double ) n;
- ybar = ybar / ( double ) n;
-//
-// Compute Beta.
-//
- top = 0.0;
- bot = 0.0;
- for ( i = 0; i < n; i++ )
- {
- top = top + ( x[i] - xbar ) * ( y[i] - ybar );
- bot = bot + ( x[i] - xbar ) * ( x[i] - xbar );
- }
-
- a = top / bot;
-
- b = ybar - a * xbar;
-
- return;
-}
-
-
-void Capture::setDirty()
-{
- mDirty = true;
-}
-
-void Capture::setMeridianFlip(bool enable)
-{
- meridianCheck->setChecked(enable);
-}
-
-void Capture::setMeridianFlipHour(double hours)
-{
- meridianHours->setValue(hours);
-}
-
-bool Capture::hasCoolerControl()
-{
- if (currentCCD && currentCCD->hasCoolerControl())
- return true;
-
- return false;
-}
-
-bool Capture::setCoolerControl(bool enable)
-{
- if (currentCCD && currentCCD->hasCoolerControl())
- return currentCCD->setCoolerControl(enable);
-
- return false;
-}
-
-void Capture::clearAutoFocusHFR()
-{
- // If HFR limit was set from file, we cannot overide it.
- if (fileHFR > 0)
- return;
-
- HFRPixels->setValue(0);
- firstAutoFocus=true;
-}
-
-void Capture::openCalibrationDialog()
-{
- QDialog calibrationDialog;
-
- Ui_calibrationOptions calibrationOptions;
- calibrationOptions.setupUi(&calibrationDialog);
-
- if (currentTelescope)
- {
- calibrationOptions.parkMountC->setEnabled(currentTelescope->canPark());
- calibrationOptions.parkMountC->setChecked(preMountPark);
- }
- else
- calibrationOptions.parkMountC->setEnabled(false);
-
- if (dome)
- {
- calibrationOptions.parkDomeC->setEnabled(dome->canPark());
- calibrationOptions.parkDomeC->setChecked(preDomePark);
- }
- else
- calibrationOptions.parkDomeC->setEnabled(false);
-
-
- //connect(calibrationOptions.wallSourceC, SIGNAL(toggled(bool)), calibrationOptions.parkC, SLOT(setDisabled(bool)));
-
- switch (flatFieldSource)
- {
- case SOURCE_MANUAL:
- calibrationOptions.manualSourceC->setChecked(true);
- break;
-
- case SOURCE_FLATCAP:
- calibrationOptions.flatDeviceSourceC->setChecked(true);
- break;
-
- case SOURCE_DARKCAP:
- calibrationOptions.darkDeviceSourceC->setChecked(true);
- break;
-
- case SOURCE_WALL:
- calibrationOptions.wallSourceC->setChecked(true);
- calibrationOptions.azBox->setText(wallCoord.az().toDMSString());
- calibrationOptions.altBox->setText(wallCoord.alt().toDMSString());
- break;
-
- case SOURCE_DAWN_DUSK:
- calibrationOptions.dawnDuskFlatsC->setChecked(true);
- break;
- }
-
- switch (flatFieldDuration)
- {
- case DURATION_MANUAL:
- calibrationOptions.manualDurationC->setChecked(true);
- break;
-
- case DURATION_ADU:
- calibrationOptions.ADUC->setChecked(true);
- calibrationOptions.ADUValue->setValue(targetADU);
- break;
- }
-
- if (calibrationDialog.exec() == QDialog::Accepted)
- {
- if (calibrationOptions.manualSourceC->isChecked())
- flatFieldSource = SOURCE_MANUAL;
- else if (calibrationOptions.flatDeviceSourceC->isChecked())
- flatFieldSource = SOURCE_FLATCAP;
- else if (calibrationOptions.darkDeviceSourceC->isChecked())
- flatFieldSource = SOURCE_DARKCAP;
- else if (calibrationOptions.wallSourceC->isChecked())
- {
- dms wallAz, wallAlt;
- bool azOk=false, altOk=false;
-
- wallAz = calibrationOptions.azBox->createDms(true, &azOk);
- wallAlt = calibrationOptions.altBox->createDms(true, &altOk);
-
- if (azOk && altOk)
- {
- flatFieldSource = SOURCE_WALL;
- wallCoord.setAz(wallAz);
- wallCoord.setAlt(wallAlt);
- }
- else
- {
- calibrationOptions.manualSourceC->setChecked(true);
- KMessageBox::error(this, i18n("Wall coordinates are invalid."));
- }
- }
- else
- flatFieldSource = SOURCE_DAWN_DUSK;
-
-
- if (calibrationOptions.manualDurationC->isChecked())
- flatFieldDuration = DURATION_MANUAL;
- else
- {
- flatFieldDuration = DURATION_ADU;
- targetADU = calibrationOptions.ADUValue->value();
- }
-
- preMountPark = calibrationOptions.parkMountC->isChecked();
- preDomePark = calibrationOptions.parkDomeC->isChecked();
-
- setDirty();
- }
-}
-
-IPState Capture::processPreCaptureCalibrationStage()
-{
- if (guideState == GUIDE_GUIDING)
- {
- appendLogText(i18n("Autoguiding suspended."));
- emit suspendGuiding(true);
- }
-
- // Let's check what actions to be taken, if any, for the flat field source
- switch (activeJob->getFlatFieldSource())
- {
- case SOURCE_MANUAL:
- case SOURCE_DAWN_DUSK: // Not yet implemented
- break;
-
- // Park cap, if not parked
- // Turn on Light
- case SOURCE_FLATCAP:
- if (dustCap)
- {
- // If cap is not park, park it
- if (calibrationStage < CAL_DUSTCAP_PARKING && dustCap->isParked() == false)
- {
- if (dustCap->Park())
- {
- calibrationStage = CAL_DUSTCAP_PARKING;
- appendLogText(i18n("Parking dust cap..."));
- return IPS_BUSY;
- }
- else
- {
- appendLogText(i18n("Parking dust cap failed, aborting..."));
- abort();
- return IPS_ALERT;
- }
- }
-
- // Wait until cap is parked
- if (calibrationStage == CAL_DUSTCAP_PARKING)
- {
- if (dustCap->isParked() == false)
- return IPS_BUSY;
- else
- {
- calibrationStage = CAL_DUSTCAP_PARKED;
- appendLogText(i18n("Dust cap parked."));
- }
- }
-
- // If light is not on, turn it on. For flat frames only
- if (activeJob->getFrameType() == FRAME_FLAT && dustCap->isLightOn() == false)
- {
- dustCapLightEnabled = true;
- dustCap->SetLightEnabled(true);
- }
- else if (activeJob->getFrameType() != FRAME_FLAT && dustCap->isLightOn() == true)
- {
- dustCapLightEnabled = false;
- dustCap->SetLightEnabled(false);
- }
- }
- break;
-
-
- // Park cap, if not parked and not flat frame
- // Unpark cap, if flat frame
- // Turn on Light
- case SOURCE_DARKCAP:
- if (dustCap)
- {
- // If cap is not park, park it if not flat frame. (external lightsource)
- if (calibrationStage < CAL_DUSTCAP_PARKING && dustCap->isParked() == false && activeJob->getFrameType() != FRAME_FLAT)
- {
- if (dustCap->Park())
- {
- calibrationStage = CAL_DUSTCAP_PARKING;
- appendLogText(i18n("Parking dust cap..."));
- return IPS_BUSY;
- }
- else
- {
- appendLogText(i18n("Parking dust cap failed, aborting..."));
- abort();
- return IPS_ALERT;
- }
- }
-
- // Wait until cap is parked
- if (calibrationStage == CAL_DUSTCAP_PARKING)
- {
- if (dustCap->isParked() == false)
- return IPS_BUSY;
- else
- {
- calibrationStage = CAL_DUSTCAP_PARKED;
- appendLogText(i18n("Dust cap parked."));
- }
- }
-
- // If cap is parked, unpark it if flat frame. (external lightsource)
- if (calibrationStage < CAL_DUSTCAP_UNPARKING && dustCap->isParked() == true && activeJob->getFrameType() == FRAME_FLAT)
- {
- if (dustCap->UnPark())
- {
- calibrationStage = CAL_DUSTCAP_UNPARKING;
- appendLogText(i18n("UnParking dust cap..."));
- return IPS_BUSY;
- }
- else
- {
- appendLogText(i18n("UnParking dust cap failed, aborting..."));
- abort();
- return IPS_ALERT;
- }
- }
-
- // Wait until cap is parked
- if (calibrationStage == CAL_DUSTCAP_UNPARKING)
- {
- if (dustCap->isParked() == true)
- return IPS_BUSY;
- else
- {
- calibrationStage = CAL_DUSTCAP_UNPARKED;
- appendLogText(i18n("Dust cap unparked."));
- }
- }
-
- // If light is not on, turn it on. For flat frames only
- if (activeJob->getFrameType() == FRAME_FLAT && dustCap->isLightOn() == false)
- {
- dustCapLightEnabled = true;
- dustCap->SetLightEnabled(true);
- }
- else if (activeJob->getFrameType() != FRAME_FLAT && dustCap->isLightOn() == true)
- {
- dustCapLightEnabled = false;
- dustCap->SetLightEnabled(false);
- }
- }
- break;
-
- // Go to wall coordinates
- case SOURCE_WALL:
- if (currentTelescope)
- {
- if (calibrationStage < CAL_SLEWING)
- {
- wallCoord = activeJob->getWallCoord();
- wallCoord.HorizontalToEquatorial(KStarsData::Instance()->lst(), KStarsData::Instance()->geo()->lat());
- currentTelescope->Slew(&wallCoord);
- appendLogText(i18n("Mount slewing to wall position..."));
- calibrationStage = CAL_SLEWING;
- return IPS_BUSY;
- }
-
- // Check if slewing is complete
- if (calibrationStage == CAL_SLEWING)
- {
- if (currentTelescope->isSlewing() == false)
- {
- calibrationStage = CAL_SLEWING_COMPLETE;
- appendLogText(i18n("Slew to wall position complete."));
- }
- else
- return IPS_BUSY;
- }
-
- if (lightBox)
- {
- // Check if we have a light box to turn on
- if (activeJob->getFrameType() == FRAME_FLAT && lightBox->isLightOn() == false)
- {
- lightBoxLightEnabled = true;
- lightBox->SetLightEnabled(true);
- }
- else if (activeJob->getFrameType() != FRAME_FLAT && lightBox->isLightOn() == true)
- {
- lightBoxLightEnabled = false;
- lightBox->SetLightEnabled(false);
- }
- }
- }
- break;
- }
-
- // Check if we need to perform mount prepark
- if (preMountPark && currentTelescope && activeJob->getFlatFieldSource() != SOURCE_WALL)
- {
- if (calibrationStage < CAL_MOUNT_PARKING && currentTelescope->isParked() == false)
- {
- if (currentTelescope->Park())
- {
- calibrationStage = CAL_MOUNT_PARKING;
- //emit mountParking();
- appendLogText(i18n("Parking mount prior to calibration frames capture..."));
- return IPS_BUSY;
- }
- else
- {
- appendLogText(i18n("Parking mount failed, aborting..."));
- abort();
- return IPS_ALERT;
- }
- }
-
- if (calibrationStage == CAL_MOUNT_PARKING)
- {
- // If not parked yet, check again in 1 second
- // Otherwise proceed to the rest of the algorithm
- if (currentTelescope->isParked() == false)
- return IPS_BUSY;
- else
- {
- calibrationStage = CAL_MOUNT_PARKED;
- appendLogText(i18n("Mount parked."));
- }
- }
- }
-
- // Check if we need to perform dome prepark
- if (preDomePark && dome)
- {
- if (calibrationStage < CAL_DOME_PARKING && dome->isParked() == false)
- {
- if (dome->Park())
- {
- calibrationStage = CAL_DOME_PARKING;
- //emit mountParking();
- appendLogText(i18n("Parking dome..."));
- return IPS_BUSY;
- }
- else
- {
- appendLogText(i18n("Parking dome failed, aborting..."));
- abort();
- return IPS_ALERT;
- }
- }
-
- if (calibrationStage == CAL_DOME_PARKING)
- {
- // If not parked yet, check again in 1 second
- // Otherwise proceed to the rest of the algorithm
- if (dome->isParked() == false)
- return IPS_BUSY;
- else
- {
- calibrationStage = CAL_DOME_PARKED;
- appendLogText(i18n("Dome parked."));
- }
- }
- }
-
- calibrationStage = CAL_PRECAPTURE_COMPLETE;
- return IPS_OK;
-}
-
-bool Capture::processPostCaptureCalibrationStage()
-{
- // Check if we need to do flat field slope calculation if the user specified a desired ADU value
- if (activeJob->getFrameType() == FRAME_FLAT && activeJob->getFlatFieldDuration() == DURATION_ADU && activeJob->getTargetADU() > 0)
- {
- FITSData *image_data = NULL;
- FITSView *currentImage = targetChip->getImage(FITS_NORMAL);
- if (currentImage)
- {
- image_data = currentImage->getImageData();
- double currentADU = image_data->getADU();
- //double currentSlope = ADUSlope;
-
- double percentageDiff=0;
- if (currentADU > activeJob->getTargetADU())
- percentageDiff = activeJob->getTargetADU()/currentADU;
- else
- percentageDiff = currentADU / activeJob->getTargetADU();
-
- // If it is within 2% of target ADU
- if (percentageDiff >= 0.98)
- {
- if (calibrationStage == CAL_CALIBRATION)
- {
- appendLogText(i18n("Current ADU %1 within target ADU tolerance range.", QString::number(currentADU, 'f', 0)));
- activeJob->setPreview(false);
- calibrationStage = CAL_CALIBRATION_COMPLETE;
- startNextExposure();
- return false;
- }
-
- return true;
- }
-
- double nextExposure = setCurrentADU(currentADU);
-
- if (nextExposure <= 0)
- {
- appendLogText(i18n("Unable to calculate optimal exposure settings, please take the flats manually."));
- //activeJob->setTargetADU(0);
- //targetADU = 0;
- abort();
- return false;
- }
-
- appendLogText(i18n("Current ADU is %1 Next exposure is %2 seconds.", QString::number(currentADU, 'f', 0), QString::number(nextExposure, 'f', 3)));
-
- calibrationStage = CAL_CALIBRATION;
- activeJob->setExposure(nextExposure);
- activeJob->setPreview(true);
-
- startNextExposure();
- return false;
-
- // Start next exposure in case ADU Slope is not calculated yet
- /*if (currentSlope == 0)
- {
- startNextExposure();
- return;
- }*/
- }
- else
- {
- appendLogText(i18n("An empty image is received, aborting..."));
- abort();
- return false;
- }
- }
-
- calibrationStage = CAL_CALIBRATION_COMPLETE;
- return true;
-}
-
-bool Capture::isSequenceFileComplete(const QString &fileURL)
-{
- // If we don't remember job progress, then no sequence would be complete
- if (Options::rememberJobProgress() == false)
- return false;
-
- // We cannot know if the job is complete if the upload mode is local since we cannot inspect the files
- if (currentCCD && currentCCD->getUploadMode() == ISD::CCD::UPLOAD_LOCAL)
- return false;
-
- if (Options::captureLogging())
- {
- qDebug() << "Capture: Loading sequence to check for completion: " << fileURL;
- }
-
- bool rc = loadSequenceQueue(fileURL);
-
- if (rc == false)
- return false;
-
- ignoreJobProgress = false;
-
- QStringList jobDirs;
- int totalJobCount = 0, totalFileCount=0;
- foreach(SequenceJob *job, jobs)
- {
- jobDirs << job->getFITSDir();
- totalJobCount += job->getCount();
- }
-
- jobDirs.removeDuplicates();
-
- if (Options::captureLogging())
- {
- qDebug() << "Capture: Total Job Count --> " << totalFileCount;
- qDebug() << "Capture: isSequenceFileComplete directories --> " << jobDirs;
- }
-
- foreach(QString dir, jobDirs)
- {
- QDir oneDir(dir);
- oneDir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
- totalFileCount += oneDir.count();
-
- if (Options::captureLogging())
- {
- qDebug() << "Capture: Directory " << dir << " file count is " << oneDir.count() << " and total count is " << totalFileCount;
- }
- }
-
- clearSequenceQueue();
-
- return (totalFileCount >= totalJobCount);
-}
-
-void Capture::setNewRemoteFile(QString file)
-{
- appendLogText(i18n("Remote image saved to %1", file));
-}
-
-void Capture::startPostFilterAutoFocus()
-{
- if (focusState >= FOCUS_PROGRESS)
- return;
-
- secondsLabel->setText(i18n("Focusing..."));
-
- state = CAPTURE_FOCUSING;
- emit newStatus(Ekos::CAPTURE_FOCUSING);
-
- appendLogText(i18n("Post filter change Autofocus..."));
-
- // Force it to always run autofocus routine
- emit checkFocus(0.1);
-}
-
-void Capture::postScriptFinished(int exitCode)
-{
- appendLogText(i18n("Post capture script finished with code %1. Resuming sequence...", exitCode));
- resumeSequence();
-}
-
-}
diff --git a/kstars/ekos/capture.h b/kstars/ekos/capture.h
deleted file mode 100644
index 34335b3..0000000
--- a/kstars/ekos/capture.h
+++ /dev/null
@@ -1,590 +0,0 @@
-/* Ekos Capture tool
- Copyright (C) 2012 Jasem Mutlaq <mutlaqja@ikarustech.com>
-
- This application is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
- */
-
-#ifndef CAPTURE_H
-#define CAPTURE_H
-
-#include <QTimer>
-#include <QUrl>
-#include <QtDBus/QtDBus>
-
-#include "ui_capture.h"
-
-#include "ekos.h"
-#include "fitsviewer/fitscommon.h"
-#include "indi/indistd.h"
-#include "indi/indiccd.h"
-#include "indi/indicap.h"
-#include "indi/indidome.h"
-#include "indi/indilightbox.h"
-#include "indi/inditelescope.h"
-
-class QProgressIndicator;
-class QTableWidgetItem;
-class KDirWatch;
-
-/**
- *@namespace Ekos
- *@short Ekos is an advanced Astrophotography tool for Linux.
- * It is based on a modular extensible framework to perform common astrophotography tasks. This includes highly accurate GOTOs using astrometry solver, ability to measure and correct polar alignment errors ,
- * auto-focus & auto-guide capabilities, and capture of single or stack of images with filter wheel support.\n
- * Features:
- * - Control your telescope, CCD (& DSLRs), filter wheel, focuser, guider, adaptive optics unit, and any INDI-compatible auxiliary device from Ekos.
- * - Extremely accurate GOTOs using astrometry.net solver (both Online and Offline solvers supported).
- * - Load & Slew: Load a FITS image, slew to solved coordinates, and center the mount on the exact image coordinates in order to get the same desired frame.
- * - Measure & Correct Polar Alignment errors using astromety.net solver.
- * - Auto and manual focus modes using Half-Flux-Radius (HFR) method.
- * - Automated unattended meridian flip. Ekos performs post meridian flip alignment, calibration, and guiding to resume the capture session.
- * - Automatic focus between exposures when a user-configurable HFR limit is exceeded.
- * - Auto guiding with support for automatic dithering between exposures and support for Adaptive Optics devices in addition to traditional guiders.
- * - Powerful sequence queue for batch capture of images with optional prefixes, timestamps, filter wheel selection, and much more!
- * - Export and import sequence queue sets as Ekos Sequence Queue (.esq) files.
- * - Center the telescope anywhere in a captured FITS image or any FITS with World Coordinate System (WCS) header.
- * - Automatic flat field capture, just set the desired ADU and let Ekos does the rest!
- * - Automatic abort and resumption of exposure tasks if guiding errors exceed a user-configurable value.
- * - Support for dome slaving.
- * - Complete integration with KStars Observation Planner and SkyMap
- * - Integrate with all INDI native devices.
- * - Powerful scripting capabilities via \ref EkosDBusInterface "DBus."
- *
- * The primary class is EkosManager. It handles startup and shutdown of local and remote INDI devices, manages and orchesterates the various Ekos modules, and provides advanced DBus
- * interface to enable unattended scripting.
-*@author Jasem Mutlaq
- *@version 1.3
- */
-namespace Ekos
-{
-
-class SequenceJob;
-
-/**
- *@class Capture
- *@short Captures single or sequence of images from a CCD.
- * The capture class support capturing single or multiple images from a CCD, it provides a powerful sequence queue with filter wheel selection. Any sequence queue can be saved as Ekos Sequence Queue (.esq).
- * All image capture operations are saved as Sequence Jobs that encapsulate all the different options in a capture process. The user may select in sequence autofocusing by setting a maximum HFR limit. When the limit
- * is exceeded, it automatically trigger autofocus operation. The capture process can also be linked with guide module. If guiding deviations exceed a certain threshold, the capture operation aborts until
- * the guiding deviation resume to acceptable levels and the capture operation is resumed.
- *@author Jasem Mutlaq
- *@version 1.2
- */
-class Capture : public QWidget, public Ui::Capture
-{
-
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.Ekos.Capture")
-
-public:
-
- enum { CALIBRATE_NONE, CALIBRATE_START, CALIBRATE_DONE };
- typedef enum { MF_NONE, MF_INITIATED, MF_FLIPPING, MF_SLEWING, MF_ALIGNING, MF_GUIDING } MFStage;
- typedef enum { CAL_NONE, CAL_DUSTCAP_PARKING, CAL_DUSTCAP_PARKED, CAL_LIGHTBOX_ON, CAL_SLEWING, CAL_SLEWING_COMPLETE, CAL_MOUNT_PARKING, CAL_MOUNT_PARKED, CAL_DOME_PARKING, CAL_DOME_PARKED, CAL_PRECAPTURE_COMPLETE, CAL_CALIBRATION, CAL_CALIBRATION_COMPLETE, CAL_CAPTURING, CAL_DUSTCAP_UNPARKING, CAL_DUSTCAP_UNPARKED} CalibrationStage;
- typedef bool (Capture::*PauseFunctionPointer)();
-
- Capture();
- ~Capture();
-
- /** @defgroup CaptureDBusInterface Ekos DBus Interface - Capture Module
- * Ekos::Capture interface provides advanced scripting capabilities to capture image sequences.
- */
-
- /*@{*/
-
- /** DBUS interface function.
- * select the CCD device from the available CCD drivers.
- * @param device The CCD device name
- */
- Q_SCRIPTABLE bool setCCD(QString device);
-
- /** DBUS interface function.
- * select the filter device from the available filter drivers. The filter device can be the same as the CCD driver if the filter functionality was embedded within the driver.
- * @param device The filter device name
- */
- Q_SCRIPTABLE bool setFilter(QString device, int filterSlot);
-
- /** DBUS interface function.
- * Aborts any current jobs and remove all sequence queue jobs.
- */
- Q_SCRIPTABLE Q_NOREPLY void clearSequenceQueue();
-
- /** DBUS interface function.
- * Returns the overall sequence queue status. If there are no jobs pending, it returns "Invalid". If all jobs are idle, it returns "Idle". If all jobs are complete, it returns "Complete". If one or more jobs are aborted
- * it returns "Aborted" unless it was temporarily aborted due to guiding deviations, then it would return "Suspended". If one or more jobs have errors, it returns "Error". If any jobs is under progress, returns "Running".
- */
- Q_SCRIPTABLE QString getSequenceQueueStatus();
-
- /** DBUS interface function.
- * Opens a sequence files and checks whether the jobs contained within are complete or not. The check is done by quering the file system for the produced files for each job.
- * If returns true if all jobs are complete, false otherwise.sudo
- */
- Q_SCRIPTABLE bool isSequenceFileComplete(const QString &fileURL);
-
- /** DBUS interface function.
- * Loads the Ekos Sequence Queue file in the Sequence Queue. Jobs are appended to existing jobs.
- * @param fileURL full URL of the filename
- */
- Q_SCRIPTABLE bool loadSequenceQueue(const QString &fileURL);
-
- /** DBUS interface function.
- * Sets target name. The target name shall be appended to the root directory specified by the user.
- * e.g. If root directory is /home/jasem and target is M31, then root directory becomes /home/jasem/M31
- * @param name Name of desired target
- */
- Q_SCRIPTABLE Q_NOREPLY void setTargetName(const QString &name) { targetName = name; }
-
- /** DBUS interface function.
- * Enables or disables the maximum guiding deviation and sets its value.
- * @param enable If true, enable the guiding deviation check, otherwise, disable it.
- * @param if enable is true, it sets the maximum guiding deviation in arcsecs. If the value is exceeded, the capture operation is aborted until the value falls below the value threshold.
- */
- Q_SCRIPTABLE Q_NOREPLY void setMaximumGuidingDeviaiton(bool enable, double value);
-
- /** DBUS interface function.
- * Enables or disables the in sequence focus and sets Half-Flux-Radius (HFR) limit.
- * @param enable If true, enable the in sequence auto focus check, otherwise, disable it.
- * @param if enable is true, it sets HFR in pixels. After each exposure, the HFR is re-measured and if it exceeds the specified value, an autofocus operation will be commanded.
- */
- Q_SCRIPTABLE Q_NOREPLY void setInSequenceFocus(bool enable, double HFR);
-
- /** DBUS interface function.
- * Enables or disables park on complete option.
- * @param enable If true, mount shall be commanded to parking position after all jobs are complete in the sequence queue.
- */
- Q_SCRIPTABLE Q_NOREPLY void setParkOnComplete(bool enable);
-
- /** DBUS interface function.
- * Enable or Disable meridian flip, and sets its activation hour.
- * @param enable If true, meridian flip will be command after user-configurable number of hours.
- */
- Q_SCRIPTABLE Q_NOREPLY void setMeridianFlip(bool enable);
-
- /** DBUS interface function.
- * Sets meridian flip trigger hour.
- * @param hours Number of hours after the meridian at which the mount is commanded to flip.
- */
- Q_SCRIPTABLE Q_NOREPLY void setMeridianFlipHour(double hours);
-
- /** DBUS interface function.
- * Does the CCD has a cooler control (On/Off) ?
- */
- Q_SCRIPTABLE bool hasCoolerControl();
-
- /** DBUS interface function.
- * Set the CCD cooler ON/OFF
- *
- */
- Q_SCRIPTABLE bool setCoolerControl(bool enable);
-
- /** DBUS interface function.
- * @return Returns the percentage of completed captures in all active jobs
- */
- Q_SCRIPTABLE double getProgressPercentage();
-
- /** DBUS interface function.
- * @return Returns the number of jobs in the sequence queue.
- */
- Q_SCRIPTABLE int getJobCount() { return jobs.count(); }
-
- /** DBUS interface function.
- * @return Returns ID of current active job if any, or -1 if there are no active jobs.
- */
- Q_SCRIPTABLE int getActiveJobID();
-
- /** DBUS interface function.
- * @return Returns time left in seconds until active job is estimated to be complete.
- */
- Q_SCRIPTABLE int getActiveJobRemainingTime();
-
- /** DBUS interface function.
- * @return Returns overall time left in seconds until all jobs are estimated to be complete
- */
- Q_SCRIPTABLE int getOverallRemainingTime();
-
- /** DBUS interface function.
- * @param id job number. Job IDs start from 0 to N-1.
- * @return Returns the job state (Idle, In Progress, Error, Aborted, Complete)
- */
- Q_SCRIPTABLE QString getJobState(int id);
-
- /** DBUS interface function.
- * @param id job number. Job IDs start from 0 to N-1.
- * @return Returns The number of images completed capture in the job.
- */
- Q_SCRIPTABLE int getJobImageProgress(int id);
-
- /** DBUS interface function.
- * @param id job number. Job IDs start from 0 to N-1.
- * @return Returns the total number of images to capture in the job.
- */
- Q_SCRIPTABLE int getJobImageCount(int id);
-
- /** DBUS interface function.
- * @param id job number. Job IDs start from 0 to N-1.
- * @return Returns the number of seconds left in an exposure operation.
- */
- Q_SCRIPTABLE double getJobExposureProgress(int id);
-
- /** DBUS interface function.
- * @param id job number. Job IDs start from 0 to N-1.
- * @return Returns the total requested exposure duration in the job.
- */
- Q_SCRIPTABLE double getJobExposureDuration(int id);
-
- /** DBUS interface function.
- * Clear in-sequence focus settings. It sets the autofocus HFR to zero so that next autofocus value is remembered for the in-sequence focusing.
- */
- Q_SCRIPTABLE Q_NOREPLY void clearAutoFocusHFR();
-
-
- /** DBUS interface function.
- * Jobs will NOT be checked for progress against the file system and will be always assumed as new jobs.
- */
- Q_SCRIPTABLE Q_NOREPLY void ignoreSequenceHistory();
-
- /** @}*/
-
- void addCCD(ISD::GDInterface *newCCD);
- void addFilter(ISD::GDInterface *newFilter);
- void setDome(ISD::GDInterface *device) { dome = dynamic_cast<ISD::Dome*>(device); }
- void setDustCap(ISD::GDInterface *device) { dustCap = dynamic_cast<ISD::DustCap*>(device); }
- void setLightBox(ISD::GDInterface *device) { lightBox = dynamic_cast<ISD::LightBox*>(device); }
- void addGuideHead(ISD::GDInterface *newCCD);
- void syncFrameType(ISD::GDInterface *ccd);
- void setTelescope(ISD::GDInterface *newTelescope);
- void syncTelescopeInfo();
- void syncFilterInfo();
-
- void clearLog();
- QString getLogText() { return logText.join("\n"); }
-
- /* Capture */
- void updateSequencePrefix( const QString &newPrefix, const QString &dir);
-
-public slots:
-
- /** \addtogroup CaptureDBusInterface
- * @{
- */
-
- /* Capture */
- /** DBUS interface function.
- * Starts the sequence queue capture procedure sequentially by starting all jobs that are either Idle or Aborted in order.
- */
- Q_SCRIPTABLE Q_NOREPLY void start();
-
- /** DBUS interface function.
- * Stop all jobs and set current job status to aborted if abort is set to true, otherwise status is idle until
- * sequence is resumed or restarted.
- * @param abort abort jobs if in progress
- */
- Q_SCRIPTABLE Q_NOREPLY void stop(bool abort=false);
-
- /** DBUS interface function.
- * Aborts all jobs. It simply calls stop(true)
- */
- Q_SCRIPTABLE Q_NOREPLY void abort() { stop(true); }
-
- /** @}*/
-
- /**
- * @brief captureOne Capture one preview image
- */
- void captureOne();
-
- /**
- * @brief captureImage Initiates image capture in the active job.
- */
- void captureImage();
-
- /**
- * @brief newFITS process new FITS data received from camera. Update status of active job and overall sequence.
- * @param bp pointer to blob contianing FITS data
- */
- void newFITS(IBLOB *bp);
-
- /**
- * @brief checkCCD Refreshes the CCD information in the capture module.
- * @param CCDNum The CCD index in the CCD combo box to select as the active CCD.
- */
- void checkCCD(int CCDNum=-1);
-
- /**
- * @brief checkFilter Refreshes the filter wheel information in the capture module.
- * @param filterNum The filter wheel index in the filter device combo box to set as the active filter.
- */
- void checkFilter(int filterNum=-1);
-
- /**
- * @brief processCCDNumber Process number properties arriving from CCD. Currently, only CCD and Guider frames are processed.
- * @param nvp pointer to number property.
- */
- void processCCDNumber(INumberVectorProperty *nvp);
-
- /**
- * @brief processTelescopeNumber Process number properties arriving from telescope for meridian flip purposes.
- * @param nvp pointer to number property.
- */
- void processTelescopeNumber(INumberVectorProperty *nvp);
-
- /**
- * @brief addJob Add a new job to the sequence queue given the settings in the GUI.
- * @param preview True if the job is a preview job, otherwise, it is added as a batch job.
- */
- void addJob(bool preview=false);
-
- /**
- * @brief removeJob Remove a job from the currently selected row. If no row is selected, it remove the last job in the queue.
- */
- void removeJob();
-
- /**
- * @brief moveJobUp Move the job in the sequence queue one place up.
- */
- void moveJobUp();
-
- /**
- * @brief moveJobDown Move the job in the sequence queue one place down.
- */
- void moveJobDown();
-
- /**
- * @brief setGuideDeviation Set the guiding deviaiton as measured by the guiding module. Abort capture if deviation exceeds user value. Resume capture if capture was aborted and guiding deviations are below user value.
- * @param delta_ra Deviation in RA in arcsecs from the selected guide star.
- * @param delta_dec Deviation in DEC in arcsecs from the selected guide star.
- */
- void setGuideDeviation(double delta_ra, double delta_dec);
-
- /**
- * @brief setGuideDither Set whether dithering is enable/disabled in guiding module.
- * @param enable True if dithering is enabled, false otherwise.
- */
- void setGuideDither(bool enable);
-
- /**
- * @brief resumeCapture Resume capture after dither and/or focusing processes are complete.
- */
- bool resumeCapture();
-
- /**
- * @brief updateCCDTemperature Update CCD temperature in capture module.
- * @param value Temperature in celcius.
- */
- void updateCCDTemperature(double value);
-
- /**
- * @brief setTemperature Set CCD temperature from the user GUI settings.
- */
- void setTemperature();
-
- // Pause Sequence Queue
- void pause();
-
- // Logs
- void appendLogText(const QString &);
-
- // Auto Focus
- void setFocusStatus(Ekos::FocusState state);
- // Guide
- void setGuideStatus(Ekos::GuideState state);
- // Align
- void setAlignStatus(Ekos::AlignState state);
-
-private slots:
-
- /**
- * @brief setDirty Set dirty bit to indicate sequence queue file was modified and needs saving.
- */
- void setDirty();
-
- void toggleSequence();
-
-
- void checkFrameType(int index);
- void resetFrame();
- void updateCaptureProgress(ISD::CCDChip *tChip, double value, IPState state);
- void checkSeqBoundary(const QString &path);
- void saveFITSDirectory();
- void setDefaultCCD(QString ccd);
- void setNewRemoteFile(QString file);
- void setGuideChip(ISD::CCDChip* chip) { guideChip = chip; }
-
- // Sequence Queue
- void loadSequenceQueue();
- void saveSequenceQueue();
- void saveSequenceQueueAs();
-
- // Jobs
- void resetJobs();
- void editJob(QModelIndex i);
- void resetJobEdit();
- void executeJob();
-
- // Meridian Flip
- void checkMeridianFlipTimeout();
- //void checkAlignmentSlewComplete();
-
- // Auto Focus
- //void updateAutofocusStatus(bool status, double HFR);
- void setHFR(double newHFR) { focusHFR = newHFR; }
- void startPostFilterAutoFocus();
-
- // Flat field
- void openCalibrationDialog();
- IPState processPreCaptureCalibrationStage();
- bool processPostCaptureCalibrationStage();
-
- // Send image info
- void sendNewImage(QImage *image, ISD::CCDChip *myChip);
-
- // Capture
- bool setCaptureComplete();
-
- // Temporary for post capture script
- void postScriptFinished(int exitCode);
-
-signals:
- void newLog();
- //void exposureComplete();
- void checkFocus(double);
- //void mountParking();
- void suspendGuiding(bool);
- void meridianFlipStarted();
- void meridianFlipCompleted();
- void newStatus(Ekos::CaptureState status);
- void newImage(QImage *image, Ekos::SequenceJob *job);
-
-private:
-
- void setBusy(bool enable);
- bool resumeSequence();
- bool startNextExposure();
- void updateFrameProperties(bool reset=false);
- void prepareJob(SequenceJob *job);
- void syncGUIToJob(SequenceJob *job);
- bool processJobInfo(XMLEle *root);
- void processJobCompletion();
- bool saveSequenceQueue(const QString &path);
- void constructPrefix(QString &imagePrefix);
- double setCurrentADU(double value);
- void llsq (QList<double> x, QList<double> y, double &a, double &b);
-
- /* Meridian Flip */
- bool checkMeridianFlip();
- void checkGuidingAfterFlip();
- double getCurrentHA();
-
- // Remaining Time in seconds
- int getJobRemainingTime(SequenceJob *job);
-
- /* Capture */
- double seqExpose;
- int seqTotalCount;
- int seqCurrentCount;
- int seqDelay;
- int retries;
- QTimer *seqTimer;
- QString seqPrefix;
- int nextSequenceID;
- int seqFileCount;
- bool isBusy;
-
- //int calibrationState;
- bool useGuideHead;
-
- QString targetName;
-
- SequenceJob *activeJob;
-
- QList<ISD::CCD *> CCDs;
-
- ISD::CCDChip *targetChip;
- ISD::CCDChip *guideChip;
-
- // They're generic GDInterface because they could be either ISD::CCD or ISD::Filter
- QList<ISD::GDInterface *> Filters;
-
- QList<SequenceJob *> jobs;
-
- ISD::Telescope *currentTelescope;
- ISD::CCD *currentCCD;
- ISD::GDInterface *currentFilter;
- ISD::DustCap *dustCap;
- ISD::LightBox *lightBox;
- ISD::Dome *dome;
-
- ITextVectorProperty *filterName;
- INumberVectorProperty *filterSlot;
-
- QStringList logText;
- QUrl sequenceURL;
- bool mDirty;
- bool jobUnderEdit;
- int currentFilterPosition;
- QProgressIndicator *pi;
-
- // Guide Deviation
- bool deviationDetected;
- bool spikeDetected;
-
- // Dither
- bool guideDither;
- //bool isAutoGuiding;
-
- // Autofocus
- bool isAutoFocus;
- bool autoFocusStatus;
- bool firstAutoFocus;
- double focusHFR; // HFR value as received from the Ekos focus module
- double fileHFR; // HFR value as loaded from the sequence file
-
- //Meridan flip
- double initialHA;
- double initialRA;
- bool resumeAlignmentAfterFlip;
- bool resumeGuidingAfterFlip;
- MFStage meridianFlipStage;
-
- // Flat field automation
- /*double ExpRaw1, ExpRaw2;
- double ADURaw1, ADURaw2;
- double ADUSlope;*/
- QList<double> ExpRaw;
- QList<double> ADURaw;
- double targetADU;
- SkyPoint wallCoord;
- bool preMountPark, preDomePark;
- FlatFieldDuration flatFieldDuration;
- FlatFieldSource flatFieldSource;
- CalibrationStage calibrationStage;
- bool dustCapLightEnabled, lightBoxLightEnabled;
-
- QUrl dirPath;
-
- // Misc
- bool ignoreJobProgress;
-
- // State
- CaptureState state;
- FocusState focusState;
- GuideState guideState;
- AlignState alignState;
-
- PauseFunctionPointer pauseFunction;
-
- // CCD Chip frame settings
- QMap<ISD::CCDChip *, QVariantMap> frameSettings;
-
- // Temporary Only
- QProcess postCaptureScript;
-
-
-};
-
-}
-
-#endif // CAPTURE_H
diff --git a/kstars/ekos/capture.ui b/kstars/ekos/capture.ui
deleted file mode 100644
index ff64248..0000000
--- a/kstars/ekos/capture.ui
+++ /dev/null
@@ -1,1602 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>Capture</class>
- <widget class="QWidget" name="Capture">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>728</width>
- <height>413</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_3">
- <property name="spacing">
- <number>1</number>
- </property>
- <property name="leftMargin">
- <number>3</number>
- </property>
- <property name="topMargin">
- <number>3</number>
- </property>
- <property name="rightMargin">
- <number>3</number>
- </property>
- <property name="bottomMargin">
- <number>3</number>
- </property>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_11">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <widget class="QGroupBox" name="CCDFWGroup">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="maximumSize">
- <size>
- <width>16777215</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="title">
- <string>CCD &amp;&amp; Filter Wheel</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <layout class="QGridLayout" name="gridLayout">
- <property name="spacing">
- <number>1</number>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="textLabel1_6">
- <property name="toolTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>CCD:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QComboBox" name="CCDCaptureCombo"/>
- </item>
- <item row="0" column="2">
- <layout class="QHBoxLayout" name="horizontalLayout_4">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <widget class="QLabel" name="textLabel1_5_3">
- <property name="toolTip">
- <string>Filter Wheel</string>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>FW:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QComboBox" name="FilterCaptureCombo">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="textLabel1_2_3">
- <property name="toolTip">
- <string>Number of images to capture</string>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>Filter:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QComboBox" name="FilterPosCombo">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="exposureLabel_2">
- <property name="toolTip">
- <string>Set the exposure time in seconds for individual images, if applicable</string>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>Exposure:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QDoubleSpinBox" name="exposureIN">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="decimals">
- <number>3</number>
- </property>
- <property name="minimum">
- <double>0.001000000000000</double>
- </property>
- <property name="maximum">
- <double>3600.000000000000000</double>
- </property>
- <property name="value">
- <double>1.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <widget class="QLabel" name="textLabel1_9">
- <property name="toolTip">
- <string>Horizontal and Vertical binning</string>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>Binning:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="textLabel1_10">
- <property name="toolTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>X:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="binXIN">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip">
- <string>Horizontal binning</string>
- </property>
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>10</number>
- </property>
- <property name="value">
- <number>1</number>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="textLabel1_11">
- <property name="toolTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>Y:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="binYIN">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip">
- <string>Vertical binning</string>
- </property>
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>10</number>
- </property>
- <property name="value">
- <number>1</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="textLabel1_12">
- <property name="toolTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>Frame:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout_9">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <widget class="QLabel" name="textLabel1_13">
- <property name="toolTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>X:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="frameXIN">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="textLabel1_14">
- <property name="toolTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>Y:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="frameYIN">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="2" column="2">
- <layout class="QHBoxLayout" name="horizontalLayout_10">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <widget class="QLabel" name="textLabel1_15">
- <property name="toolTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>W:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="frameWIN">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="maximum">
- <number>99</number>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="textLabel1_16">
- <property name="toolTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>H:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="frameHIN">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="resetFrameB">
- <property name="minimumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Reset CCD frame values to default values</string>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="textLabel1_17">
- <property name="toolTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>Type:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QComboBox" name="frameTypeCombo">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- <item row="3" column="2">
- <layout class="QHBoxLayout" name="horizontalLayout_12">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <widget class="QCheckBox" name="temperatureCheck">
- <property name="toolTip">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enforce temperature value before capturing an image&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- <property name="text">
- <string>TÂș</string>
- </property>
- <property name="checked">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="temperatureOUT">
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QDoubleSpinBox" name="temperatureIN">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="setTemperatureB">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="toolTip">
- <string>Set CCD temperature</string>
- </property>
- <property name="text">
- <string>Set</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="calibrationB">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Calibration Options</string>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="4" column="0">
- <widget class="QLabel" name="textLabel1_7">
- <property name="toolTip">
- <string>Prefix to append to the beginning of file names</string>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>Prefix:</string>
- </property>
- </widget>
- </item>
- <item row="4" column="1">
- <widget class="QLineEdit" name="prefixIN"/>
- </item>
- <item row="4" column="2">
- <layout class="QHBoxLayout" name="horizontalLayout_16">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <widget class="QCheckBox" name="filterCheck">
- <property name="toolTip">
- <string>Append the active filter slot to the prefix</string>
- </property>
- <property name="text">
- <string>Filter</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="expDurationCheck">
- <property name="toolTip">
- <string>Append the expose duration to the prefix</string>
- </property>
- <property name="text">
- <string>Duration</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="ISOCheck">
- <property name="toolTip">
- <string>Append time stamp to the prefix</string>
- </property>
- <property name="text">
- <string>TS</string>
- </property>
- <property name="checked">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item row="5" column="0">
- <widget class="QLabel" name="textLabel1_4">
- <property name="toolTip">
- <string>Number of images to capture</string>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>Count:</string>
- </property>
- </widget>
- </item>
- <item row="5" column="1">
- <widget class="QSpinBox" name="countIN">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- <property name="value">
- <number>1</number>
- </property>
- </widget>
- </item>
- <item row="5" column="2">
- <layout class="QHBoxLayout" name="horizontalLayout_3">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <widget class="QLabel" name="textLabel1_8">
- <property name="toolTip">
- <string>Delay in seconds between consecutive images</string>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>Delay:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="delayIN">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="maximum">
- <number>3600</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="6" column="0">
- <widget class="QLabel" name="label_8">
- <property name="toolTip">
- <string>Apply filter to image after capture to enhance it</string>
- </property>
- <property name="text">
- <string>Filters:</string>
- </property>
- </widget>
- </item>
- <item row="6" column="1">
- <widget class="QComboBox" name="filterCombo">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <item>
- <property name="text">
- <string>--</string>
- </property>
- </item>
- </widget>
- </item>
- <item row="6" column="2">
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <widget class="QLabel" name="ISOLabel">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>ISO:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QComboBox" name="ISOCombo">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_8">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <widget class="QLabel" name="textLabel1_18">
- <property name="toolTip">
- <string>Directory to save sequence images</string>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>Directory:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="fitsDir"/>
- </item>
- <item>
- <widget class="QPushButton" name="selectFITSDirB">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>28</width>
- <height>28</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>28</width>
- <height>28</height>
- </size>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="verticalSpacer_3">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <layout class="QVBoxLayout" name="SequenceQueue">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <widget class="QGroupBox" name="groupBox">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title">
- <string>Sequence Queue</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_8">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_14">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <widget class="QPushButton" name="addToQueueB">
- <property name="minimumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="text">
- <string/>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">queueEditButtonGroup</string>
- </attribute>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="removeFromQueueB">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="minimumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="text">
- <string/>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">queueEditButtonGroup</string>
- </attribute>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="queueUpB">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="minimumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="text">
- <string/>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">queueEditButtonGroup</string>
- </attribute>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="queueDownB">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="minimumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="text">
- <string/>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">queueEditButtonGroup</string>
- </attribute>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="resetB">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="minimumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Reset status of all jobs</string>
- </property>
- <property name="text">
- <string/>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">queueEditButtonGroup</string>
- </attribute>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="queueLoadB">
- <property name="minimumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="text">
- <string/>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">queueEditButtonGroup</string>
- </attribute>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="queueSaveB">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="minimumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="text">
- <string/>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">queueEditButtonGroup</string>
- </attribute>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="queueSaveAsB">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="minimumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="text">
- <string/>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">queueEditButtonGroup</string>
- </attribute>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QTableWidget" name="queueTable">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="horizontalScrollBarPolicy">
- <enum>Qt::ScrollBarAsNeeded</enum>
- </property>
- <attribute name="horizontalHeaderDefaultSectionSize">
- <number>85</number>
- </attribute>
- <attribute name="horizontalHeaderMinimumSectionSize">
- <number>30</number>
- </attribute>
- <column>
- <property name="text">
- <string>Status</string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>Filter</string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>Type</string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>Bin</string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>Exp</string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>ISO</string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>Count</string>
- </property>
- </column>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_7">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <widget class="QPushButton" name="previewB">
- <property name="toolTip">
- <string/>
- </property>
- <property name="text">
- <string>Preview</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="buttonSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Expanding</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>18</width>
- <height>21</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="startB">
- <property name="minimumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Start Sequence</string>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="autoDefault">
- <bool>true</bool>
- </property>
- <property name="default">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="pauseB">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="minimumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Pause Sequence</string>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="autoDefault">
- <bool>true</bool>
- </property>
- <property name="default">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_13">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <widget class="QGroupBox" name="optionsGroup">
- <property name="title">
- <string>Options</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_5">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <widget class="QCheckBox" name="darkSubCheck">
- <property name="toolTip">
- <string>Perform automatic dark subtraction in preview mode</string>
- </property>
- <property name="text">
- <string>Auto dark subtract</string>
- </property>
- <property name="checked">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer_3">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QGridLayout" name="gridLayout_2">
- <property name="spacing">
- <number>1</number>
- </property>
- <item row="0" column="0">
- <widget class="QCheckBox" name="guideDeviationCheck">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="toolTip">
- <string>Abort sequence if guiding deviation exceed this value</string>
- </property>
- <property name="text">
- <string>Guiding Deviation &lt;</string>
- </property>
- <property name="checked">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QDoubleSpinBox" name="guideDeviation">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="decimals">
- <number>2</number>
- </property>
- <property name="maximum">
- <double>30.000000000000000</double>
- </property>
- <property name="singleStep">
- <double>0.500000000000000</double>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QLabel" name="textLabel1_2_4">
- <property name="toolTip">
- <string>Number of images to capture</string>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>&quot;</string>
- </property>
- </widget>
- </item>
- <item row="0" column="6">
- <widget class="QLabel" name="textLabel1_2_5">
- <property name="toolTip">
- <string>Number of images to capture</string>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>pixels</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QCheckBox" name="meridianCheck">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="toolTip">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Command a meridian flip if the hour angle exceeds the specified value. Capture and Guiding will be suspended and resumed after the flip is complete.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- <property name="text">
- <string>Meridian Flip if HA &gt;</string>
- </property>
- </widget>
- </item>
- <item row="1" column="4" colspan="2">
- <widget class="QCheckBox" name="parkCheck">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="toolTip">
- <string>Automatically park telescope once all sequence jobs are completed</string>
- </property>
- <property name="text">
- <string>Park When Complete</string>
- </property>
- </widget>
- </item>
- <item row="0" column="5">
- <widget class="QDoubleSpinBox" name="HFRPixels">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="decimals">
- <number>3</number>
- </property>
- <property name="minimum">
- <double>0.000000000000000</double>
- </property>
- <property name="maximum">
- <double>10.000000000000000</double>
- </property>
- <property name="singleStep">
- <double>0.100000000000000</double>
- </property>
- <property name="value">
- <double>0.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QLabel" name="textLabel1_2_6">
- <property name="toolTip">
- <string>Number of images to capture</string>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>hours</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QDoubleSpinBox" name="meridianHours">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="decimals">
- <number>2</number>
- </property>
- <property name="minimum">
- <double>0.000000000000000</double>
- </property>
- <property name="maximum">
- <double>3.000000000000000</double>
- </property>
- <property name="singleStep">
- <double>0.100000000000000</double>
- </property>
- <property name="value">
- <double>0.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="0" column="4">
- <widget class="QCheckBox" name="autofocusCheck">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="toolTip">
- <string>Perform autofocusing once Half-Flux-Radius (HFR) value exceeds this limit</string>
- </property>
- <property name="text">
- <string>Autofocus if HFR &gt;</string>
- </property>
- </widget>
- </item>
- <item row="0" column="3">
- <widget class="Line" name="line">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- </widget>
- </item>
- <item row="1" column="3">
- <widget class="Line" name="line_2">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="verticalSpacer_2">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="progressGroup">
- <property name="title">
- <string>Progress</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_7">
- <property name="spacing">
- <number>3</number>
- </property>
- <property name="leftMargin">
- <number>3</number>
- </property>
- <property name="topMargin">
- <number>3</number>
- </property>
- <property name="rightMargin">
- <number>3</number>
- </property>
- <property name="bottomMargin">
- <number>3</number>
- </property>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_6">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <layout class="QGridLayout" name="progressLayout">
- <property name="spacing">
- <number>5</number>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="progressLabel_3">
- <property name="text">
- <string>Expose:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="exposeOUT">
- <property name="minimumSize">
- <size>
- <width>50</width>
- <height>0</height>
- </size>
- </property>
- <property name="frameShape">
- <enum>QFrame::Box</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="0" column="2" colspan="2">
- <widget class="QLabel" name="secondsLabel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>85</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>85</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string notr="true">second left</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="progressLabel_2">
- <property name="text">
- <string>Progress:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLabel" name="currentImgCountOUT">
- <property name="minimumSize">
- <size>
- <width>50</width>
- <height>0</height>
- </size>
- </property>
- <property name="frameShape">
- <enum>QFrame::Box</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QLabel" name="textLabel1_4_2_3">
- <property name="text">
- <string>of</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- </widget>
- </item>
- <item row="1" column="3">
- <widget class="QLabel" name="fullImgCountOUT">
- <property name="minimumSize">
- <size>
- <width>50</width>
- <height>0</height>
- </size>
- </property>
- <property name="frameShape">
- <enum>QFrame::Box</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="1" column="4">
- <widget class="QLabel" name="completedLabel_2">
- <property name="text">
- <string>completed</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="progressSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Expanding</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>51</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QProgressBar" name="imgProgress">
- <property name="enabled">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer_4">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>1</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>2</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- <zorder>verticalSpacer</zorder>
- </widget>
- <resources/>
- <connections/>
- <buttongroups>
- <buttongroup name="queueEditButtonGroup">
- <property name="exclusive">
- <bool>false</bool>
- </property>
- </buttongroup>
- </buttongroups>
-</ui>
diff --git a/kstars/ekos/darklibrary.cpp b/kstars/ekos/darklibrary.cpp
deleted file mode 100644
index b068cdb..0000000
--- a/kstars/ekos/darklibrary.cpp
+++ /dev/null
@@ -1,282 +0,0 @@
-/* Ekos Dark Library Handler
- Copyright (C) 2016 Jasem Mutlaq <mutlaqja@ikarustech.com>
-
- This application is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
- */
-
-#include <QVariantMap>
-
-#include "darklibrary.h"
-#include "Options.h"
-
-#include "kstars.h"
-#include "kspaths.h"
-#include "kstarsdata.h"
-#include "fitsviewer/fitsview.h"
-#include "fitsviewer/fitsdata.h"
-#include "auxiliary/ksuserdb.h"
-
-namespace Ekos
-{
-
-DarkLibrary * DarkLibrary::_DarkLibrary = NULL;
-
-DarkLibrary * DarkLibrary::Instance()
-{
- if (_DarkLibrary == NULL)
- _DarkLibrary = new DarkLibrary(KStars::Instance());
-
- return _DarkLibrary;
-}
-
-DarkLibrary::DarkLibrary(QObject *parent) : QObject(parent)
-{
- KStarsData::Instance()->userdb()->GetAllDarkFrames(darkFrames);
-
-
- subtractParams.duration=0;
- subtractParams.offsetX=0;
- subtractParams.offsetY=0;
- subtractParams.targetChip=0;
- subtractParams.targetImage=0;
-
- QDir writableDir;
- writableDir.mkdir(KSPaths::writableLocation(QStandardPaths::GenericDataLocation) + "darks");
-}
-
-DarkLibrary::~DarkLibrary()
-{
- qDeleteAll(darkFiles);
-}
-
-FITSData * DarkLibrary::getDarkFrame(ISD::CCDChip *targetChip, double duration)
-{
- foreach(QVariantMap map, darkFrames)
- {
- // First check CCD name matches
- if (map["ccd"].toString() == targetChip->getCCD()->getDeviceName())
- {
- // Then check we are on the correct chip
- if (map["chip"].toInt() == static_cast<int>(targetChip->getType()))
- {
- int binX, binY;
- targetChip->getBinning(&binX, &binY);
-
- // Then check if binning is the same
- if (map["binX"].toInt() == binX && map["binY"].toInt() == binY)
- {
- // Then check for temperature
- if (targetChip->getCCD()->hasCooler())
- {
- double temperature=0;
- targetChip->getCCD()->getTemperature(&temperature);
- // TODO make this configurable value, the threshold
- if (fabs(map["temperature"].toDouble()-temperature) > Options::maxDarkTemperatureDiff())
- continue;
- }
-
- // Then check for duration
- // TODO make this value configurable
- if (fabs(map["duration"].toDouble() - duration) > 0.05)
- continue;
-
- // Finaly check if the duration is acceptable
- QDateTime frameTime = QDateTime::fromString(map["timestamp"].toString(), Qt::ISODate);
- if (frameTime.daysTo(QDateTime::currentDateTime()) > Options::darkLibraryDuration())
- continue;
-
- QString filename = map["filename"].toString();
-
- if (darkFiles.contains(filename))
- return darkFiles[filename];
-
- // Finally we made it, let's put it in the hash
- bool rc = loadDarkFile(filename);
- if (rc)
- return darkFiles[filename];
- else
- return NULL;
- }
- }
- }
- }
-
- return NULL;
-}
-
-bool DarkLibrary::loadDarkFile(const QString &filename)
-{
- FITSData *darkData = new FITSData();
-
- bool rc = darkData->loadFITS(filename);
-
- if (rc)
- darkFiles[filename] = darkData;
- else
- {
- emit newLog(i18n("Failed to load dark frame file %1", filename));
- delete (darkData);
- }
-
- return rc;
-}
-
-bool DarkLibrary::saveDarkFile(FITSData *darkData)
-{
- QDateTime ts = QDateTime::currentDateTime();
-
- QString path = KSPaths::writableLocation(QStandardPaths::GenericDataLocation) + "darks/darkframe_" + ts.toString(Qt::ISODate) + ".fits";
-
- if (darkData->saveFITS(path) != 0)
- return false;
-
- darkFiles[path] = darkData;
-
- QVariantMap map;
- int binX, binY;
- double temperature=0;
-
- subtractParams.targetChip->getBinning(&binX, &binY);
- subtractParams.targetChip->getCCD()->getTemperature(&temperature);
-
- map["ccd"] = subtractParams.targetChip->getCCD()->getDeviceName();
- map["chip"] = static_cast<int>(subtractParams.targetChip->getType());
- map["binX"] = binX;
- map["binY"] = binY;
- map["temperature"] = temperature;
- map["duration"] = subtractParams.duration;
- map["filename"] = path;
-
- darkFrames.append(map);
-
- emit newLog(i18n("Dark frame saved to %1", path));
-
- KStarsData::Instance()->userdb()->AddDarkFrame(map);
-
- return true;
-}
-
-bool DarkLibrary::subtract(FITSData *darkData, FITSView *lightImage, FITSScale filter, uint16_t offsetX, uint16_t offsetY)
-{
- Q_ASSERT(darkData);
- Q_ASSERT(lightImage);
-
- FITSData *lightData = lightImage->getImageData();
-
- float *darkBuffer = darkData->getImageBuffer();
- float *lightBuffer = lightData->getImageBuffer();
-
- int darkoffset = offsetX + offsetY * darkData->getWidth();
- int darkW = darkData->getWidth();
-
- int lightOffset = 0;
- int lightW = lightData->getWidth();
- int lightH = lightData->getHeight();
-
- for (int i=0; i < lightH; i++)
- {
- for (int j=0; j < lightW; j++)
- {
- lightBuffer[j+lightOffset] -= darkBuffer[j+darkoffset];
- if (lightBuffer[j+lightOffset] < 0)
- lightBuffer[j+lightOffset] = 0;
- }
-
- lightOffset += lightW;
- darkoffset += darkW;
- }
-
- lightData->applyFilter(filter);
- lightImage->rescale(ZOOM_KEEP_LEVEL);
- lightImage->updateFrame();
-
- emit darkFrameCompleted(true);
-
- return true;
-}
-
-void DarkLibrary::captureAndSubtract(ISD::CCDChip *targetChip, FITSView*targetImage, double duration, uint16_t offsetX, uint16_t offsetY)
-{
- QStringList shutterfulCCDs = Options::shutterfulCCDs();
- QStringList shutterlessCCDs = Options::shutterlessCCDs();
- QString deviceName = targetChip->getCCD()->getDeviceName();
-
- bool hasShutter = shutterfulCCDs.contains(deviceName);
- bool hasNoShutter = shutterlessCCDs.contains(deviceName);
-
- // If no information is available either way, then ask the user
- if (hasShutter == false && hasNoShutter == false)
- {
- if (KMessageBox::questionYesNo(NULL, i18n("Does %1 have mechanical or electronic shutter?", deviceName), i18n("Dark Exposure")) == KMessageBox::Yes)
- {
- hasShutter = true;
- hasNoShutter = false;
- shutterfulCCDs.append(deviceName);
- Options::setShutterfulCCDs(shutterfulCCDs);
- }
- else
- {
- hasShutter = false;
- hasNoShutter = true;
- shutterlessCCDs.append(deviceName);
- Options::setShutterlessCCDs(shutterlessCCDs);
- }
- }
-
- if (hasNoShutter)
- {
- KMessageBox::information(NULL, i18n("Cover the telescope or camera in order to take a dark exposure."), i18n("Dark Exposure"), "dark_exposure_dialog_notification");
- }
-
- targetChip->resetFrame();
- targetChip->setCaptureMode(FITS_CALIBRATE);
- targetChip->setFrameType(FRAME_DARK);
-
- subtractParams.targetChip = targetChip;
- subtractParams.targetImage= targetImage;
- subtractParams.duration = duration;
- subtractParams.offsetX = offsetX;
- subtractParams.offsetY = offsetY;
-
- connect(targetChip->getCCD(), SIGNAL(BLOBUpdated(IBLOB*)), this, SLOT(newFITS(IBLOB*)));
-
- emit newLog(i18n("Capturing dark frame..."));
-
- targetChip->capture(duration);
-}
-
-void DarkLibrary::newFITS(IBLOB *bp)
-{
- INDI_UNUSED(bp);
-
- Q_ASSERT(subtractParams.targetChip);
-
- disconnect(subtractParams.targetChip->getCCD(), SIGNAL(BLOBUpdated(IBLOB*)), this, SLOT(newFITS(IBLOB*)));
-
- FITSView *calibrationView = subtractParams.targetChip->getImage(FITS_CALIBRATE);
-
- emit newLog(i18n("Dark frame received."));
-
- FITSData *calibrationData = new FITSData();
-
- // Deep copy of the data
- if (calibrationData->loadFITS(calibrationView->getImageData()->getFilename()))
- {
- saveDarkFile(calibrationData);
- subtract(calibrationData, subtractParams.targetImage, subtractParams.targetChip->getCaptureFilter(), subtractParams.offsetX, subtractParams.offsetY);
- }
- else
- {
- emit darkFrameCompleted(false);
- emit newLog(i18n("Warning: Cannot load calibration file %1", calibrationView->getImageData()->getFilename()));
- }
-}
-
-}
-
-
-
-
diff --git a/kstars/ekos/darklibrary.h b/kstars/ekos/darklibrary.h
deleted file mode 100644
index 67a4692..0000000
--- a/kstars/ekos/darklibrary.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Ekos Dark Library Handler
- Copyright (C) 2016 Jasem Mutlaq <mutlaqja@ikarustech.com>
-
- This application is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
- */
-
-#ifndef DARKLIBRARY_H
-#define DARKLIBRARY_H
-
-#include <QObject>
-#include "indi/indiccd.h"
-
-namespace Ekos
-{
-
-/**
- *@class DarkLibrary
- *@short Handles aquisition & loading of dark frames for cameras. If a suitable dark frame exists, it is loaded from disk, otherwise it gets captured and saved
- * for later use.
- *@author Jasem Mutlaq
- *@version 1.0
- */
-class DarkLibrary : public QObject
-{
-
- Q_OBJECT
-
-public:
-
- static DarkLibrary *Instance();
-
- FITSData * getDarkFrame(ISD::CCDChip *targetChip, double duration);
- bool subtract(FITSData *darkData, FITSView *lightImage, FITSScale filter, uint16_t offsetX, uint16_t offsetY);
- void captureAndSubtract(ISD::CCDChip *targetChip, FITSView*targetImage, double duration, uint16_t offsetX, uint16_t offsetY);
-
-signals:
- void darkFrameCompleted(bool);
- void newLog(const QString &message);
-
-public slots:
- /**
- * @brief newFITS A new FITS blob is received by the CCD driver.
- * @param bp pointer to blob data
- */
- void newFITS(IBLOB *bp);
-
-private:
- DarkLibrary(QObject *parent);
- ~DarkLibrary();
- static DarkLibrary * _DarkLibrary;
-
- bool loadDarkFile(const QString &filename);
- bool saveDarkFile(FITSData *darkData);
-
- QList<QVariantMap> darkFrames;
- QHash<QString, FITSData *> darkFiles;
-
- struct
- {
- ISD::CCDChip *targetChip;
- double duration;
- uint16_t offsetX;
- uint16_t offsetY;
- FITSView *targetImage;
- FITSScale filter;
- } subtractParams;
-
-
-};
-
-}
-
-#endif // DARKLIBRARY_H
diff --git a/kstars/ekos/dome.cpp b/kstars/ekos/dome.cpp
deleted file mode 100644
index 7e9c1a3..0000000
--- a/kstars/ekos/dome.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
-/* Ekos
- Copyright (C) 2012 Jasem Mutlaq <mutlaqja@ikarustech.com>
-
- This application is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
- */
-
-#include "dome.h"
-#include "ekosmanager.h"
-#include "kstars.h"
-#include "domeadaptor.h"
-
-#include <basedevice.h>
-
-
-namespace Ekos
-{
-
-Dome::Dome()
-{
- new DomeAdaptor(this);
- QDBusConnection::sessionBus().registerObject("/KStars/Ekos/Dome", this);
-
- currentDome = NULL;
-}
-
-Dome::~Dome()
-{
-
-}
-
-void Dome::setDome(ISD::GDInterface *newDome)
-{
- currentDome = static_cast<ISD::Dome *>(newDome);
-}
-
-bool Dome::canPark()
-{
- if (currentDome == NULL)
- return false;
-
- return currentDome->canPark();
-}
-
-bool Dome::park()
-{
- if (currentDome == NULL || currentDome->canPark() == false)
- return false;
-
- return currentDome->Park();
-}
-
-bool Dome::unpark()
-{
- if (currentDome == NULL || currentDome->canPark() == false)
- return false;
-
- return currentDome->UnPark();
-}
-
-bool Dome::abort()
-{
- if (currentDome == NULL)
- return false;
-
- return currentDome->Abort();
-}
-
-bool Dome::isMoving()
-{
- if (currentDome == NULL)
- return false;
-
- return currentDome->isMoving();
-}
-
-Dome::ParkingStatus Dome::getParkingStatus()
-{
- if (currentDome == NULL || currentDome->canPark() == false)
- return PARKING_ERROR;
-
- ISwitchVectorProperty *parkSP = currentDome->getBaseDevice()->getSwitch("DOME_PARK");
-
- if (parkSP == NULL)
- return PARKING_ERROR;
-
- switch (parkSP->s)
- {
- case IPS_IDLE:
- return PARKING_IDLE;
-
- case IPS_OK:
- if (parkSP->sp[0].s == ISS_ON)
- return PARKING_OK;
- else
- return UNPARKING_OK;
- break;
-
- case IPS_BUSY:
- if (parkSP->sp[0].s == ISS_ON)
- return PARKING_BUSY;
- else
- return UNPARKING_BUSY;
-
- case IPS_ALERT:
- return PARKING_ERROR;
- }
-
- return PARKING_ERROR;
-}
-
-
-
-}
-
-
diff --git a/kstars/ekos/dome.h b/kstars/ekos/dome.h
deleted file mode 100644
index 9046f16..0000000
--- a/kstars/ekos/dome.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Ekos Dome interface
- Copyright (C) 2015 Jasem Mutlaq <mutlaqja@ikarustech.com>
-
- This application is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
- */
-
-#ifndef DOME_H
-#define DOME_H
-
-#include <QtDBus/QtDBus>
-
-#include "indi/indistd.h"
-#include "indi/indidome.h"
-
-namespace Ekos
-{
-
-/**
- *@class Dome
- *@short Supports basic dome functions
- *@author Jasem Mutlaq
- *@version 1.0
- */
-class Dome : public QObject
-{
-
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.Ekos.Dome")
-
-public:
- Dome();
- ~Dome();
-
- typedef enum { PARKING_IDLE, PARKING_OK, UNPARKING_OK, PARKING_BUSY, UNPARKING_BUSY, PARKING_ERROR } ParkingStatus;
-
- /** @defgroup DomeDBusInterface Ekos DBus Interface - Dome Interface
- * Ekos::Dome interface provides advanced basic dome operations.
- */
-
- /*@{*/
-
- /** DBUS interface function.
- * Abort dome
- */
- Q_SCRIPTABLE bool abort();
-
- /** DBUS interface function.
- * Can dome park?
- */
- Q_SCRIPTABLE bool canPark();
-
- /** DBUS interface function.
- * Park dome
- */
- Q_SCRIPTABLE bool park();
-
- /** DBUS interface function.
- * Park dome
- */
- Q_SCRIPTABLE bool unpark();
-
- /** DBUS interface function.
- * Get the dome park status
- */
- Q_SCRIPTABLE ParkingStatus getParkingStatus();
-
- /** DBUS interface function.
- * Check if the dome is in motion
- */
- Q_SCRIPTABLE bool isMoving();
-
- /** @}*/
-
- /**
- * @brief setDome set the dome device
- * @param newDome pointer to Dome device.
- */
- void setDome(ISD::GDInterface *newDome);
-
-private:
-
- // Devices needed for Dome operation
- ISD::Dome *currentDome;
-
-};
-
-}
-
-#endif // Dome_H
diff --git a/kstars/ekos/dustcap.cpp b/kstars/ekos/dustcap.cpp
deleted file mode 100644
index b83eb35..0000000
--- a/kstars/ekos/dustcap.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/* Ekos DustCap Interface
- Copyright (C) 2015 Jasem Mutlaq <mutlaqja@ikarustech.com>
-
- This application is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
- */
-
-#include "dustcap.h"
-#include "ekosmanager.h"
-#include "kstars.h"
-#include "dustcapadaptor.h"
-
-#include <basedevice.h>
-
-
-namespace Ekos
-{
-
-DustCap::DustCap()
-{
- new DustCapAdaptor(this);
- QDBusConnection::sessionBus().registerObject("/KStars/Ekos/DustCap", this);
-
- currentDustCap = NULL;
-}
-
-DustCap::~DustCap()
-{
-
-}
-
-void DustCap::setDustCap(ISD::GDInterface *newDustCap)
-{
- currentDustCap = static_cast<ISD::DustCap *>(newDustCap);
-}
-
-DustCap::ParkingStatus DustCap::getParkingStatus()
-{
- if (currentDustCap == NULL)
- return PARKING_ERROR;
-
- ISwitchVectorProperty *parkSP = currentDustCap->getBaseDevice()->getSwitch("CAP_PARK");
-
- if (parkSP == NULL)
- return PARKING_ERROR;
-
- switch (parkSP->s)
- {
- case IPS_IDLE:
- return PARKING_IDLE;
-
- case IPS_OK:
- if (parkSP->sp[0].s == ISS_ON)
- return PARKING_OK;
- else
- return UNPARKING_OK;
- break;
-
- case IPS_BUSY:
- if (parkSP->sp[0].s == ISS_ON)
- return PARKING_BUSY;
- else
- return UNPARKING_BUSY;
-
- case IPS_ALERT:
- return PARKING_ERROR;
- }
-
- return PARKING_ERROR;
-}
-
-bool DustCap::park()
-{
- if (currentDustCap == NULL)
- return false;
-
- return currentDustCap->Park();
-}
-
-bool DustCap::unpark()
-{
- if (currentDustCap == NULL)
- return false;
-
- return currentDustCap->UnPark();
-}
-
-bool DustCap::canPark()
-{
- if (currentDustCap == NULL)
- return false;
-
- return currentDustCap->canPark();
-}
-
-bool DustCap::hasLight()
-{
- if (currentDustCap == NULL)
- return false;
-
- return currentDustCap->hasLight();
-}
-
-bool DustCap::setLightEnabled(bool enable)
-{
- if (currentDustCap == NULL)
- return false;
-
- return currentDustCap->SetLightEnabled(enable);
-}
-
-bool DustCap::setBrightness(uint16_t val)
-{
- if (currentDustCap == NULL)
- return false;
-
- return currentDustCap->SetBrightness(val);
-}
-
-}
-
-
diff --git a/kstars/ekos/dustcap.h b/kstars/ekos/dustcap.h
deleted file mode 100644
index db1f000..0000000
--- a/kstars/ekos/dustcap.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* Ekos DustCap interface
- Copyright (C) 2015 Jasem Mutlaq <mutlaqja@ikarustech.com>
-
- This application is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
- */
-
-#ifndef DUSTCAP_H
-#define DUSTCAP_H
-
-#include <QtDBus/QtDBus>
-
-#include "indi/indistd.h"
-#include "indi/indicap.h"
-
-namespace Ekos
-{
-
-/**
- *@class DustCap
- *@short Supports basic DustCap functions (open/close) and optionally control flat light
- *@author Jasem Mutlaq
- *@version 1.0
- */
-class DustCap : public QObject
-{
-
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.Ekos.DustCap")
-
-public:
-
- typedef enum { PARKING_IDLE, PARKING_OK, UNPARKING_OK, PARKING_BUSY, UNPARKING_BUSY, PARKING_ERROR } ParkingStatus;
-
- DustCap();
- ~DustCap();
-
- /** @defgroup DustCapDBusInterface Ekos DBus Interface - DustCap Interface
- * Ekos::DustCap interface provides basic DustCap operations.
- */
-
- /*@{*/
-
- /** DBUS interface function.
- * If dust cap can park/unpark or is it just a light source?
- * @return True if park is supported, false otherwise
- */
- Q_SCRIPTABLE bool canPark();
-
- /** DBUS interface function.
- * Park / Close dust cap
- * @return True if operation started/successful, false otherwise
- */
- Q_SCRIPTABLE bool park();
-
- /** DBUS interface function.
- * UnPark / Open dust cap
- * @return True if operation started/successful, false otherwise
- */
- Q_SCRIPTABLE bool unpark();
-
- /** DBUS interface function.
- * hasLight: Does the dust cap have a flat light source?
- * @return True if there if flat light, false othereise
- */
- Q_SCRIPTABLE bool hasLight();
-
- /** DBUS interface function.
- * setLightEnabled: Turn on/off light box
- * @param enable If true, turn light on, otherwise turn light off
- * @return True if operation started/successful, false otherwise
- */
- Q_SCRIPTABLE bool setLightEnabled(bool enable);
-
- /** DBUS interface function.
- * SetLight: Set light source brightness level
- * @return True if operation started/successful, false otherwise
- */
- Q_SCRIPTABLE bool setBrightness(uint16_t val);
-
- /** DBUS interface function.
- * Get the dome park status
- */
- Q_SCRIPTABLE ParkingStatus getParkingStatus();
-
- /** @}*/
-
- /**
- * @brief setDustCap set the DustCap device
- * @param newDustCap pointer to DustCap device.
- */
- void setDustCap(ISD::GDInterface *newDustCap);
-
-private:
-
- // Devices needed for DustCap operation
- ISD::DustCap *currentDustCap;
-
-};
-
-}
-
-#endif // DustCap_H
diff --git a/kstars/ekos/focus.cpp b/kstars/ekos/focus.cpp
deleted file mode 100644
index 88b4d22..0000000
--- a/kstars/ekos/focus.cpp
+++ /dev/null
@@ -1,2332 +0,0 @@
-/* Ekos
- Copyright (C) 2012 Jasem Mutlaq <mutlaqja@ikarustech.com>
-
- This application is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
- */
-
-#include "focus.h"
-#include "Options.h"
-
-#include <KMessageBox>
-#include <KLocalizedString>
-#include <KPlotting/KPlotWidget>
-#include <KPlotting/KPlotObject>
-#include <KPlotting/KPlotAxis>
-
-#include <KNotifications/KNotification>
-
-#include "indi/driverinfo.h"
-#include "indi/indicommon.h"
-#include "indi/clientmanager.h"
-#include "indi/indifilter.h"
-
-#include "auxiliary/kspaths.h"
-
-#include "fitsviewer/fitsviewer.h"
-#include "fitsviewer/fitstab.h"
-#include "fitsviewer/fitsview.h"
-#include "ekosmanager.h"
-#include "darklibrary.h"
-
-#include "kstars.h"
-#include "focusadaptor.h"
-
-#include <basedevice.h>
-
-#define MAXIMUM_ABS_ITERATIONS 30
-#define MAXIMUM_RESET_ITERATIONS 2
-#define DEFAULT_SUBFRAME_DIM 128
-#define AUTO_STAR_TIMEOUT 45000
-#define MINIMUM_PULSE_TIMER 32
-#define MAX_RECAPTURE_RETRIES 3
-
-namespace Ekos
-{
-
-Focus::Focus()
-{
- setupUi(this);
-
- new FocusAdaptor(this);
- QDBusConnection::sessionBus().registerObject("/KStars/Ekos/Focus", this);
-
- currentFocuser = NULL;
- currentCCD = NULL;
- currentFilter = NULL;
- filterName = NULL;
- filterSlot = NULL;
-
- canAbsMove = false;
- canRelMove = false;
- inAutoFocus = false;
- inFocusLoop = false;
- captureInProgress = false;
- inSequenceFocus = false;
- //starSelected = false;
- //frameModified = false;
- subFramed = false;
- resetFocus = false;
- m_autoFocusSuccesful = false;
- filterPositionPending= false;
-
- rememberUploadMode = ISD::CCD::UPLOAD_CLIENT;
- HFRInc =0;
- noStarCount=0;
- reverseDir = false;
- initialFocuserAbsPosition = -1;
-
- state = Ekos::FOCUS_IDLE;
-
- pulseDuration = 1000;
-
- resetFocusIteration=0;
- //fy=fw=fh=0;
- //orig_x = orig_y = orig_w = orig_h =-1;
- lockedFilterIndex=-1;
- maxHFR=1;
- minimumRequiredHFR = -1;
- currentFilterIndex=-1;
- minPos=1e6;
- maxPos=0;
- frameNum=0;
-
- connect(startFocusB, SIGNAL(clicked()), this, SLOT(start()));
- connect(stopFocusB, SIGNAL(clicked()), this, SLOT(checkStopFocus()));
-
- connect(focusOutB, SIGNAL(clicked()), this, SLOT(FocusOut()));
- connect(focusInB, SIGNAL(clicked()), this, SLOT(FocusIn()));
-
- connect(captureB, SIGNAL(clicked()), this, SLOT(capture()));
-
- connect(AutoModeR, SIGNAL(toggled(bool)), this, SLOT(toggleAutofocus(bool)));
-
- connect(startLoopB, SIGNAL(clicked()), this, SLOT(startFraming()));
-
- connect(kcfg_subFrame, SIGNAL(toggled(bool)), this, SLOT(toggleSubframe(bool)));
-
- connect(resetFrameB, SIGNAL(clicked()), this, SLOT(resetFrame()));
-
- connect(CCDCaptureCombo, SIGNAL(activated(QString)), this, SLOT(setDefaultCCD(QString)));
- connect(CCDCaptureCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(checkCCD(int)));
-
- connect(focuserCombo, SIGNAL(activated(int)), this, SLOT(checkFocuser(int)));
- connect(FilterCaptureCombo, SIGNAL(activated(int)), this, SLOT(checkFilter(int)));
- connect(FilterPosCombo, SIGNAL(activated(int)), this, SLOT(updateFilterPos(int)));
- connect(lockFilterCheck, SIGNAL(toggled(bool)), this, SLOT(filterLockToggled(bool)));
- connect(setAbsTicksB, SIGNAL(clicked()), this, SLOT(setAbsoluteFocusTicks()));
- connect(binningCombo, SIGNAL(activated(int)), this, SLOT(setActiveBinning(int)));
- connect(focusBoxSize, SIGNAL(valueChanged(int)), this, SLOT(updateBoxSize(int)));
-
- activeBin=Options::focusXBin();
- binningCombo->setCurrentIndex(activeBin-1);
-
- connect(clearDataB, SIGNAL(clicked()) , this, SLOT(clearDataPoints()));
-
- lastFocusDirection = FOCUS_NONE;
-
- focusType = FOCUS_MANUAL;
-
- profilePlot->setBackground(QBrush(Qt::black));
- profilePlot->xAxis->setBasePen(QPen(Qt::white, 1));
- profilePlot->yAxis->setBasePen(QPen(Qt::white, 1));
- profilePlot->xAxis->grid()->setPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine));
- profilePlot->yAxis->grid()->setPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine));
- profilePlot->xAxis->grid()->setSubGridPen(QPen(QColor(80, 80, 80), 1, Qt::DotLine));
- profilePlot->yAxis->grid()->setSubGridPen(QPen(QColor(80, 80, 80), 1, Qt::DotLine));
- profilePlot->xAxis->grid()->setZeroLinePen(Qt::NoPen);
- profilePlot->yAxis->grid()->setZeroLinePen(Qt::NoPen);
- profilePlot->xAxis->setBasePen(QPen(Qt::white, 1));
- profilePlot->yAxis->setBasePen(QPen(Qt::white, 1));
- profilePlot->xAxis->setTickPen(QPen(Qt::white, 1));
- profilePlot->yAxis->setTickPen(QPen(Qt::white, 1));
- profilePlot->xAxis->setSubTickPen(QPen(Qt::white, 1));
- profilePlot->yAxis->setSubTickPen(QPen(Qt::white, 1));
- profilePlot->xAxis->setTickLabelColor(Qt::white);
- profilePlot->yAxis->setTickLabelColor(Qt::white);
- profilePlot->xAxis->setLabelColor(Qt::white);
- profilePlot->yAxis->setLabelColor(Qt::white);
-
- firstGaus = NULL;
-
- currentGaus = profilePlot->addGraph();
- currentGaus->setLineStyle(QCPGraph::lsLine);
- currentGaus->setPen(QPen(Qt::red, 2));
-
- lastGaus = profilePlot->addGraph();
- lastGaus->setLineStyle(QCPGraph::lsLine);
- QPen pen(Qt::darkGreen);
- pen.setStyle(Qt::DashLine);
- pen.setWidth(2);
- lastGaus->setPen(pen);
-
- HFRPlot->setBackground(QBrush(Qt::black));
-
- HFRPlot->xAxis->setBasePen(QPen(Qt::white, 1));
- HFRPlot->yAxis->setBasePen(QPen(Qt::white, 1));
-
- HFRPlot->xAxis->setTickPen(QPen(Qt::white, 1));
- HFRPlot->yAxis->setTickPen(QPen(Qt::white, 1));
-
- HFRPlot->xAxis->setSubTickPen(QPen(Qt::white, 1));
- HFRPlot->yAxis->setSubTickPen(QPen(Qt::white, 1));
-
- HFRPlot->xAxis->setTickLabelColor(Qt::white);
- HFRPlot->yAxis->setTickLabelColor(Qt::white);
-
- HFRPlot->xAxis->setLabelColor(Qt::white);
- HFRPlot->yAxis->setLabelColor(Qt::white);
-
- HFRPlot->xAxis->grid()->setPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine));
- HFRPlot->yAxis->grid()->setPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine));
- HFRPlot->xAxis->grid()->setSubGridPen(QPen(QColor(80, 80, 80), 1, Qt::DotLine));
- HFRPlot->yAxis->grid()->setSubGridPen(QPen(QColor(80, 80, 80), 1, Qt::DotLine));
- HFRPlot->xAxis->grid()->setZeroLinePen(Qt::NoPen);
- HFRPlot->yAxis->grid()->setZeroLinePen(Qt::NoPen);
-
- HFRPlot->yAxis->setLabel(i18n("HFR"));
-
- v_graph = HFRPlot->addGraph();
- v_graph->setLineStyle(QCPGraph::lsNone);
- v_graph->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, Qt::white, Qt::red, 3));
-
- resetButtons();
-
- appendLogText(i18n("Idle."));
-
- foreach(QString filter, FITSViewer::filterTypes)
- filterCombo->addItem(filter);
-
- filterCombo->setCurrentIndex(Options::focusEffect());
- defaultScale = static_cast<FITSScale>(Options::focusEffect());
- connect(filterCombo, SIGNAL(activated(int)), this, SLOT(filterChangeWarning(int)));
-
- exposureIN->setValue(Options::focusExposure());
- toleranceIN->setValue(Options::focusTolerance());
- stepIN->setValue(Options::focusTicks());
- kcfg_autoSelectStar->setChecked(Options::autoSelectStar());
- focusBoxSize->setValue(Options::focusBoxSize());
- maxTravelIN->setValue(Options::focusMaxTravel());
- kcfg_subFrame->setChecked(Options::focusSubFrame());
- suspendGuideCheck->setChecked(Options::suspendGuiding());
- lockFilterCheck->setChecked(Options::lockFocusFilter());
- darkFrameCheck->setChecked(Options::useFocusDarkFrame());
- thresholdSpin->setValue(Options::focusThreshold());
- focusFramesSpin->setValue(Options::focusFrames());
-
- connect(thresholdSpin, SIGNAL(valueChanged(double)), this, SLOT(setThreshold(double)));
- connect(focusFramesSpin, SIGNAL(valueChanged(int)), this, SLOT(setFrames(int)));
-}
-
-Focus::~Focus()
-{
- //qDeleteAll(HFRAbsolutePoints);
- // HFRAbsolutePoints.clear();
-}
-
-void Focus::toggleAutofocus(bool enable)
-{
- if (enable)
- {
- focusType = FOCUS_AUTO;
- drawHFRPlot();
- }
- else
- {
- focusType = FOCUS_MANUAL;
- drawHFRPlot();
- }
-
- if (inFocusLoop || inAutoFocus)
- abort();
- else
- resetButtons();
-}
-
-void Focus::resetFrame()
-{
- if (currentCCD)
- {
- ISD::CCDChip *targetChip = currentCCD->getChip(ISD::CCDChip::PRIMARY_CCD);
-
- if (targetChip)
- {
- //fx=fy=fw=fh=0;
- targetChip->resetFrame();
-
- int x,y,w,h;
- targetChip->getFrame(&x,&y,&w, &h);
-
- QVariantMap settings;
- settings["x"] = x;
- settings["y"] = y;
- settings["w"] = w;
- settings["h"] = h;
- settings["binx"] = 1;
- settings["biny"] = 1;
- frameSettings[targetChip] = settings;
- //targetChip->setFocusFrame(0,0,0,0);
-
- //starSelected = false;
- starCenter = QVector3D();
- subFramed = false;
-
- FITSView *targetImage = targetChip->getImage(FITS_FOCUS);
- if (targetImage)
- targetImage->setTrackingBox(QRect());
- }
- }
-}
-
-bool Focus::setCCD(QString device)
-{
- for (int i=0; i < CCDCaptureCombo->count(); i++)
- if (device == CCDCaptureCombo->itemText(i))
- {
- CCDCaptureCombo->setCurrentIndex(i);
- return true;
- }
-
- return false;
-}
-
-void Focus::setDefaultCCD(QString ccd)
-{
- Options::setDefaultFocusCCD(ccd);
-}
-
-void Focus::checkCCD(int ccdNum)
-{
- if (ccdNum == -1)
- {
- ccdNum = CCDCaptureCombo->currentIndex();
-
- if (ccdNum == -1)
- return;
- }
-
- if (ccdNum >=0 && ccdNum <= CCDs.count())
- {
- currentCCD = CCDs.at(ccdNum);
-
- ISD::CCDChip *targetChip = currentCCD->getChip(ISD::CCDChip::PRIMARY_CCD);
- if (targetChip)
- {
- binningCombo->setEnabled(targetChip->canBin());
- kcfg_subFrame->setEnabled(targetChip->canSubframe());
- kcfg_autoSelectStar->setEnabled(targetChip->canSubframe());
- if (targetChip->canBin())
- {
- int subBinX=1,subBinY=1;
- binningCombo->clear();
- targetChip->getMaxBin(&subBinX, &subBinY);
- for (int i=1; i <= subBinX; i++)
- binningCombo->addItem(QString("%1x%2").arg(i).arg(i));
-
- binningCombo->setCurrentIndex(activeBin-1);
-
- }
-
- QStringList isoList = targetChip->getISOList();
- ISOCombo->clear();
-
- if (isoList.isEmpty())
- {
- ISOCombo->setEnabled(false);
- ISOLabel->setEnabled(false);
- }
- else
- {
- ISOCombo->setEnabled(true);
- ISOLabel->setEnabled(true);
- ISOCombo->addItems(isoList);
- ISOCombo->setCurrentIndex(targetChip->getISOIndex());
- }
-
- }
- }
-
- syncCCDInfo();
-}
-
-void Focus::syncCCDInfo()
-{
-
- if (currentCCD == NULL)
- return;
-
- ISD::CCDChip *targetChip = currentCCD->getChip(ISD::CCDChip::PRIMARY_CCD);
-
- if (frameSettings.contains(targetChip) == false)
- {
- int x,y,w,h;
- if (targetChip->getFrame(&x, &y, &w, &h))
- {
- int binx=1,biny=1;
- targetChip->getBinning(&binx, &biny);
- if (w > 0 && h > 0)
- {
- QVariantMap settings;
-
- settings["x"] = x;
- settings["y"] = y;
- settings["w"] = w;
- settings["h"] = h;
- settings["binx"] = binx;
- settings["biny"] = biny;
-
- frameSettings[targetChip] = settings;
- }
- }
- }
-}
-
-void Focus::addFilter(ISD::GDInterface *newFilter)
-{
- foreach(ISD::GDInterface *filter, Filters)
- {
- if (!strcmp(filter->getDeviceName(), newFilter->getDeviceName()))
- return;
- }
-
- FilterCaptureLabel->setEnabled(true);
- FilterCaptureCombo->setEnabled(true);
- FilterPosLabel->setEnabled(true);
- FilterPosCombo->setEnabled(true);
- lockFilterCheck->setEnabled(true);
-
- FilterCaptureCombo->addItem(newFilter->getDeviceName());
-
- Filters.append(static_cast<ISD::Filter *>(newFilter));
-
- checkFilter(0);
-
- FilterCaptureCombo->setCurrentIndex(0);
-
-}
-
-bool Focus::setFilter(QString device, int filterSlot)
-{
- bool deviceFound=false;
-
- for (int i=0; i < FilterCaptureCombo->count(); i++)
- if (device == FilterCaptureCombo->itemText(i))
- {
- checkFilter(i);
- deviceFound = true;
- break;
- }
-
- if (deviceFound == false)
- return false;
-
- if (filterSlot < FilterCaptureCombo->count())
- FilterCaptureCombo->setCurrentIndex(filterSlot);
-
- return true;
-}
-
-void Focus::checkFilter(int filterNum)
-{
- if (filterNum == -1)
- {
- filterNum = FilterCaptureCombo->currentIndex();
- if (filterNum == -1)
- return;
- }
-
- QStringList filterAlias = Options::filterAlias();
-
- if (filterNum <= Filters.count())
- currentFilter = Filters.at(filterNum);
-
- FilterPosCombo->clear();
-
- filterName = currentFilter->getBaseDevice()->getText("FILTER_NAME");
- filterSlot = currentFilter->getBaseDevice()->getNumber("FILTER_SLOT");
-
- if (filterSlot == NULL)
- {
- KMessageBox::error(0, i18n("Unable to find FILTER_SLOT property in driver %1", currentFilter->getBaseDevice()->getDeviceName()));
- return;
- }
-
- currentFilterIndex = filterSlot->np[0].value - 1;
-
- for (int i=0; i < filterSlot->np[0].max; i++)
- {
- QString item;
-
- if (filterName != NULL && (i < filterName->ntp))
- item = filterName->tp[i].text;
- else if (i < filterAlias.count() && filterAlias[i].isEmpty() == false)
- item = filterAlias.at(i);
- else
- item = QString("Filter_%1").arg(i+1);
-
- FilterPosCombo->addItem(item);
-
- }
-
- if (lockFilterCheck->isChecked() == false)
- FilterPosCombo->setCurrentIndex( currentFilterIndex);
- else
- {
- if (lockedFilterIndex < 0)
- {
- //lockedFilterIndex = currentFilterIndex;
- lockedFilterIndex = Options::lockFocusFilterIndex();
- emit filterLockUpdated(currentFilter, lockedFilterIndex);
- }
- FilterPosCombo->setCurrentIndex(lockedFilterIndex);
- }
-
- // If we are waiting to change the filter wheel, let's check if the condition is now met.
- if (filterPositionPending)
- {
- if (lockedFilterIndex == currentFilterIndex)
- {
- filterPositionPending = false;
- capture();
- }
- }
-
-}
-
-void Focus::filterLockToggled(bool enable)
-{
- if (enable)
- {
- lockedFilterIndex = FilterPosCombo->currentIndex();
- if (lockedFilterIndex >= 0)
- Options::setLockFocusFilterIndex(lockedFilterIndex);
- emit filterLockUpdated(currentFilter, lockedFilterIndex);
- }
- else if (filterSlot != NULL)
- {
- FilterPosCombo->setCurrentIndex(filterSlot->np[0].value-1);
- emit filterLockUpdated(NULL, 0);
- }
-}
-
-void Focus::updateFilterPos(int index)
-{
- if (lockFilterCheck->isChecked() == true)
- {
- lockedFilterIndex = index;
- Options::setLockFocusFilterIndex(lockedFilterIndex);
- emit filterLockUpdated(currentFilter, lockedFilterIndex);
- }
-}
-
-void Focus::addFocuser(ISD::GDInterface *newFocuser)
-{
- focuserCombo->addItem(newFocuser->getDeviceName());
-
- Focusers.append(static_cast<ISD::Focuser*>(newFocuser));
-
- currentFocuser = static_cast<ISD::Focuser *> (newFocuser);
-
- checkFocuser();
-}
-
-bool Focus::setFocuser(QString device)
-{
- for (int i=0; i < focuserCombo->count(); i++)
- if (device == focuserCombo->itemText(i))
- {
- checkFocuser(i);
- return true;
- }
-
- return false;
-}
-
-void Focus::checkFocuser(int FocuserNum)
-{
- if (FocuserNum == -1)
- FocuserNum = focuserCombo->currentIndex();
-
- if (FocuserNum <= Focusers.count())
- currentFocuser = Focusers.at(FocuserNum);
-
- if (currentFocuser->canAbsMove())
- {
- canAbsMove = true;
- getAbsFocusPosition();
-
- absTicksSpin->setEnabled(true);
- setAbsTicksB->setEnabled(true);
- }
- else
- {
- canAbsMove = false;
- absTicksSpin->setEnabled(false);
- setAbsTicksB->setEnabled(false);
- }
-
- if (currentFocuser->canRelMove())
- {
- // We pretend this is an absolute focuser
- canRelMove = true;
- currentPosition = 50000;
- absMotionMax = 100000;
- absMotionMin = 0;
- }
-
- connect(currentFocuser, SIGNAL(numberUpdated(INumberVectorProperty*)), this, SLOT(processFocusNumber(INumberVectorProperty*)), Qt::UniqueConnection);
-
- AutoModeR->setEnabled(true);
-
- resetButtons();
-
- //if (!inAutoFocus && !inFocusLoop && !captureInProgress && !inSequenceFocus)
- // emit autoFocusFinished(true, -1);
-}
-
-void Focus::addCCD(ISD::GDInterface *newCCD)
-{
- if (CCDs.contains(static_cast<ISD::CCD *>(newCCD)))
- return;
-
- CCDs.append(static_cast<ISD::CCD *>(newCCD));
-
- CCDCaptureCombo->addItem(newCCD->getDeviceName());
-
- //checkCCD(CCDs.count()-1);
- //CCDCaptureCombo->setCurrentIndex(CCDs.count()-1);
-}
-
-void Focus::getAbsFocusPosition()
-{
- INumberVectorProperty *absMove = NULL;
- if (canAbsMove)
- {
- absMove = currentFocuser->getBaseDevice()->getNumber("ABS_FOCUS_POSITION");
-
- if (absMove)
- {
- currentPosition = absMove->np[0].value;
- absMotionMax = absMove->np[0].max;
- absMotionMin = absMove->np[0].min;
-
- absTicksSpin->setMinimum(absMove->np[0].min);
- absTicksSpin->setMaximum(absMove->np[0].max);
- absTicksSpin->setSingleStep(absMove->np[0].step);
-
- absTicksSpin->setValue(currentPosition);
- }
- }
-
-}
-
-void Focus::start()
-{
- if (currentCCD == NULL)
- {
- appendLogText(i18n("No CCD connected."));
- return;
- }
-
- lastFocusDirection = FOCUS_NONE;
-
- lastHFR = 0;
-
- if (canAbsMove)
- {
- absIterations = 0;
- getAbsFocusPosition();
- pulseDuration = stepIN->value();
- }
- else if (canRelMove)
- {
- appendLogText(i18n("Setting dummy central position to 50000"));
- absIterations = 0;
- pulseDuration = stepIN->value();
- currentPosition = 50000;
- absMotionMax = 100000;
- absMotionMin = 0;
- }
- else
- {
- pulseDuration=stepIN->value();
-
- if (pulseDuration <= MINIMUM_PULSE_TIMER)
- {
- appendLogText(i18n("Starting pulse step is too low. Increase the step size to %1 or higher...", MINIMUM_PULSE_TIMER*5));
- return;
- }
- }
-
- inAutoFocus = true;
- m_autoFocusSuccesful = false;
- frameNum=0;
-
- resetButtons();
-
- reverseDir = false;
-
- /*if (fw > 0 && fh > 0)
- starSelected= true;
- else
- starSelected= false;*/
-
- clearDataPoints();
-
- if (firstGaus)
- {
- profilePlot->removeGraph(firstGaus);
- firstGaus = NULL;
- }
-
- Options::setFocusTicks(stepIN->value());
- Options::setFocusTolerance(toleranceIN->value());
- Options::setFocusExposure(exposureIN->value());
- Options::setFocusXBin(activeBin);
- Options::setFocusMaxTravel(maxTravelIN->value());
-
- Options::setFocusSubFrame(kcfg_subFrame->isChecked());
- Options::setAutoSelectStar(kcfg_autoSelectStar->isChecked());
- Options::setSuspendGuiding(suspendGuideCheck->isChecked());
- Options::setLockFocusFilter(lockFilterCheck->isChecked());
- Options::setUseFocusDarkFrame(darkFrameCheck->isChecked());
-
- if (Options::focusLogging())
- qDebug() << "Focus: Starting focus with box size: " << focusBoxSize->value() << " Step Size: " << stepIN->value() << " Threshold: " << thresholdSpin->value() << " Tolerance: " << toleranceIN->value()
- << " Frames: " << focusFramesSpin->value() << " Maximum Travel: " << maxTravelIN->value();
-
- if (kcfg_autoSelectStar->isChecked())
- appendLogText(i18n("Autofocus in progress..."));
- else
- appendLogText(i18n("Please wait until image capture is complete..."));
-
- if (suspendGuideCheck->isChecked())
- emit suspendGuiding(true);
-
- //emit statusUpdated(true);
- state = Ekos::FOCUS_PROGRESS;
- emit newStatus(state);
-
- // Denoise with median filter
- //defaultScale = FITS_MEDIAN;
-
- capture();
-}
-
-void Focus::checkStopFocus()
-{
- if (inSequenceFocus == true)
- {
- inSequenceFocus = false;
- setAutoFocusResult(false);
- }
-
- if (captureInProgress && inAutoFocus == false && inFocusLoop == false)
- {
- captureB->setEnabled(true);
- stopFocusB->setEnabled(false);
-
- appendLogText(i18n("Capture aborted."));
- }
-
- abort();
-}
-
-void Focus::abort()
-{
- if (Options::focusLogging())
- qDebug() << "Focus: Stopppig Focus";
-
- ISD::CCDChip *targetChip = currentCCD->getChip(ISD::CCDChip::PRIMARY_CCD);
-
- inAutoFocus = false;
- inFocusLoop = false;
- //starSelected= false;
- minimumRequiredHFR = -1;
- noStarCount = 0;
- frameNum=0;
- //maxHFR=1;
-
- disconnect(currentCCD, SIGNAL(BLOBUpdated(IBLOB*)), this, SLOT(newFITS(IBLOB*)));
-
- if (rememberUploadMode != currentCCD->getUploadMode())
- currentCCD->setUploadMode(rememberUploadMode);
-
- targetChip->abortExposure();
-
- //resetFrame();
-
- FITSView *targetImage = targetChip->getImage(FITS_FOCUS);
- if (targetImage)
- targetImage->updateMode(FITS_FOCUS);
-
- resetButtons();
-
- absIterations = 0;
- HFRInc=0;
- reverseDir = false;
-
- //emit statusUpdated(false);
- state = Ekos::FOCUS_ABORTED;
- emit newStatus(state);
-}
-
-void Focus::capture()
-{
- if (currentCCD == NULL)
- {
- appendLogText(i18n("No CCD connected."));
- return;
- }
-
- ISD::CCDChip *targetChip = currentCCD->getChip(ISD::CCDChip::PRIMARY_CCD);
-
- double seqExpose = exposureIN->value();
-
- if (currentCCD->isConnected() == false)
- {
- appendLogText(i18n("Error: Lost connection to CCD."));
- return;
- }
-
- if (currentFilter != NULL && lockFilterCheck->isChecked())
- {
- if (currentFilter->isConnected() == false)
- {
- appendLogText(i18n("Error: Lost connection to filter wheel."));
- return;
- }
-
- if (lockedFilterIndex != currentFilterIndex)
- {
- int lockedFilterPosition = lockedFilterIndex + 1;
- filterPositionPending = true;
- appendLogText(i18n("Changing filter to %1", FilterPosCombo->currentText()));
- currentFilter->runCommand(INDI_SET_FILTER, &lockedFilterPosition);
- return;
- }
- }
-
- if (currentCCD->getUploadMode() == ISD::CCD::UPLOAD_LOCAL)
- {
- rememberUploadMode = ISD::CCD::UPLOAD_LOCAL;
- currentCCD->setUploadMode(ISD::CCD::UPLOAD_CLIENT);
- }
-
- targetChip->setBinning(activeBin, activeBin);
-
- targetChip->setCaptureMode(FITS_FOCUS);
-
- // Always disable filtering if using a dark frame and then re-apply after subtraction. TODO: Implement this in capture and guide and align
- if (darkFrameCheck->isChecked())
- targetChip->setCaptureFilter(FITS_NONE);
- else
- targetChip->setCaptureFilter(defaultScale);
-
- if (ISOCombo->isEnabled() && ISOCombo->currentIndex() != -1 && targetChip->getISOIndex() != ISOCombo->currentIndex())
- targetChip->setISOIndex(ISOCombo->currentIndex());
-
- connect(currentCCD, SIGNAL(BLOBUpdated(IBLOB*)), this, SLOT(newFITS(IBLOB*)));
-
- targetChip->setFrameType(FRAME_LIGHT);
-
- if (frameSettings.contains(targetChip))
- {
- QVariantMap settings = frameSettings[targetChip];
- targetChip->setFrame(settings["x"].toInt(), settings["y"].toInt(), settings["w"].toInt(), settings["h"].toInt());
- settings["binx"] = activeBin;
- settings["biny"] = activeBin;
- frameSettings[targetChip] = settings;
- }
-
- captureInProgress = true;
-
- targetChip->capture(seqExpose);
-
- if (inFocusLoop == false)
- {
- appendLogText(i18n("Capturing image..."));
-
- if (inAutoFocus == false)
- {
- captureB->setEnabled(false);
- stopFocusB->setEnabled(true);
- }
- }
-}
-
-void Focus::FocusIn(int ms)
-{
- if (currentFocuser == NULL)
- return;
-
- if (currentFocuser->isConnected() == false)
- {
- appendLogText(i18n("Error: Lost connection to Focuser."));
- return;
- }
-
- if (ms == -1)
- ms = stepIN->value();
-
- if (Options::focusLogging())
- qDebug() << "Focus: Focus in (" << ms << ")" ;
-
- lastFocusDirection = FOCUS_IN;
-
- currentFocuser->focusIn();
-
- if (canAbsMove)
- {
- currentFocuser->moveAbs(currentPosition-ms);
- appendLogText(i18n("Focusing inward..."));
- }
- else if (canRelMove)
- {
- currentFocuser->moveRel(ms);
- appendLogText(i18n("Focusing inward..."));
- }
- else
- {
- currentFocuser->moveByTimer(ms);
- appendLogText(i18n("Focusing inward by %1 ms...", ms));
- }
-
-
-
-}
-
-void Focus::FocusOut(int ms)
-{
- if (currentFocuser == NULL)
- return;
-
- if (currentFocuser->isConnected() == false)
- {
- appendLogText(i18n("Error: Lost connection to Focuser."));
- return;
- }
-
- lastFocusDirection = FOCUS_OUT;
-
- if (ms == -1)
- ms = stepIN->value();
-
- if (Options::focusLogging())
- qDebug() << "Focus: Focus out (" << ms << ")" ;
-
- currentFocuser->focusOut();
-
- if (canAbsMove)
- {
- currentFocuser->moveAbs(currentPosition+ms);
- appendLogText(i18n("Focusing outward..."));
- }
- else if (canRelMove)
- {
- currentFocuser->moveRel(ms);
- appendLogText(i18n("Focusing outward..."));
- }
- else
- {
- currentFocuser->moveByTimer(ms);
- appendLogText(i18n("Focusing outward by %1 ms...", ms));
- }
-}
-
-void Focus::newFITS(IBLOB *bp)
-{
- if (bp == NULL)
- {
- capture();
- return;
- }
-
- // Ignore guide head if there is any.
- if (!strcmp(bp->name, "CCD2"))
- return;
-
- ISD::CCDChip *targetChip = currentCCD->getChip(ISD::CCDChip::PRIMARY_CCD);
- disconnect(currentCCD, SIGNAL(BLOBUpdated(IBLOB*)), this, SLOT(newFITS(IBLOB*)));
-
- if (darkFrameCheck->isChecked())
- {
- FITSView *currentImage = targetChip->getImage(FITS_FOCUS);
- FITSData *darkData = NULL;
- QVariantMap settings = frameSettings[targetChip];
- uint16_t offsetX = settings["x"].toInt() / settings["binx"].toInt();
- uint16_t offsetY = settings["y"].toInt() / settings["biny"].toInt();
-
- darkData = DarkLibrary::Instance()->getDarkFrame(targetChip, exposureIN->value());
-
- connect(DarkLibrary::Instance(), SIGNAL(darkFrameCompleted(bool)), this, SLOT(setCaptureComplete()));
- connect(DarkLibrary::Instance(), SIGNAL(newLog(QString)), this, SLOT(appendLogText(QString)));
-
- if (darkData)
- DarkLibrary::Instance()->subtract(darkData, currentImage, defaultScale, offsetX, offsetY);
- else
- DarkLibrary::Instance()->captureAndSubtract(targetChip, currentImage, exposureIN->value(), offsetX, offsetY);
-
- return;
- }
-
- setCaptureComplete();
-}
-
-void Focus::setCaptureComplete()
-{
- DarkLibrary::Instance()->disconnect(this);
-
- ISD::CCDChip *targetChip = currentCCD->getChip(ISD::CCDChip::PRIMARY_CCD);
-
- // Always reset capture mode to NORMAL
- targetChip->setCaptureMode(FITS_NORMAL);
-
- FITSView *targetImage = targetChip->getImage(FITS_FOCUS);
-
- if (targetImage == NULL)
- {
- appendLogText(i18n("FITS image failed to load, aborting..."));
- abort();
- return;
- }
-
- int subBinX=1, subBinY=1;
- targetChip->getBinning(&subBinX, &subBinY);
-
- if (starCenter.isNull() == false)
- {
- // If binning changed, update coords accordingly
- if (subBinX != starCenter.z())
- {
- starCenter.setX(starCenter.x() * (starCenter.z()/subBinX));
- starCenter.setY(starCenter.y() * (starCenter.z()/subBinY));
- starCenter.setZ(subBinX);
- }
-
- QRect starRect = QRect( (starCenter.x()-focusBoxSize->value()/(2*subBinX)), starCenter.y()-focusBoxSize->value()/(2*subBinY), focusBoxSize->value()/subBinX, focusBoxSize->value()/subBinY);
- targetImage->setTrackingBox(starRect);
- }
-
- connect(targetImage, SIGNAL(trackingStarSelected(int,int)), this, SLOT(focusStarSelected(int, int)), Qt::UniqueConnection);
-
- if (inFocusLoop == false)
- appendLogText(i18n("Image received."));
-
- if (captureInProgress && inFocusLoop == false && inAutoFocus==false)
- {
- captureB->setEnabled(true);
- stopFocusB->setEnabled(false);
- currentCCD->setUploadMode(rememberUploadMode);
- }
-
- captureInProgress = false;
-
- FITSData *image_data = targetChip->getImageData();
-
- starPixmap = targetImage->getTrackingBoxPixmap();
- emit newStarPixmap(starPixmap);
-
- // If we're not framing, let's try to detect stars
- if (inFocusLoop == false || (inFocusLoop && targetImage->isTrackingBoxEnabled()))
- {
- if (image_data->areStarsSearched() == false)
- {
- if (targetImage->isTrackingBoxEnabled())
- image_data->findStars(targetImage->getTrackingBox());
- else
- image_data->findStars();
- }
-
- currentHFR= image_data->getHFR(HFR_MAX);
-
- /*if (currentHFR == -1)
- {
- currentHFR = image_data->getHFR();
- }*/
-
- if (Options::focusLogging())
- qDebug() << "Focus newFITS #" << frameNum+1 << ": Current HFR " << currentHFR;
-
- HFRFrames[frameNum++] = currentHFR;
-
- if (frameNum >= focusFramesSpin->value())
- {
- currentHFR=0;
- for (int i=0; i < frameNum; i++)
- currentHFR+= HFRFrames[i];
-
- currentHFR /= frameNum;
- frameNum =0;
- }
- else
- {
- capture();
- return;
- }
-
- emit newHFR(currentHFR);
-
- QString HFRText = QString("%1").arg(currentHFR, 0,'g', 3);
-
- if (focusType == FOCUS_MANUAL && lastHFR == -1)
- appendLogText(i18n("FITS received. No stars detected."));
-
- HFROut->setText(HFRText);
-
- if (currentHFR > 0)
- {
- // Center tracking box around selected star
- //if (starSelected && inAutoFocus)
- if (starCenter.isNull() == false && inAutoFocus)
- {
- Edge *maxStarHFR = image_data->getMaxHFRStar();
-
- if (maxStarHFR)
- {
- //int x = qMax(0, static_cast<int>(maxStarHFR->x-focusBoxSize->value()/(2*subBinX)));
- //int y = qMax(0, static_cast<int>(maxStarHFR->y-focusBoxSize->value()/(2*subBinY)));
-
- //targetImage->setTrackingBox(QRect(x, y, focusBoxSize->value(), focusBoxSize->value()));
- starCenter.setX(qMax(0, static_cast<int>(maxStarHFR->x)));
- starCenter.setY(qMax(0, static_cast<int>(maxStarHFR->y)));
- targetImage->setTrackingBox(QRect( (starCenter.x()-focusBoxSize->value()/(2*subBinX)), starCenter.y()-focusBoxSize->value()/(2*subBinY), focusBoxSize->value()/subBinX, focusBoxSize->value()/subBinY));
- }
- }
-
- if (currentHFR > maxHFR)
- maxHFR = currentHFR;
-
- if (hfr_position.empty())
- hfr_position.append(1);
- else
- hfr_position.append(hfr_position.last()+1);
- hfr_value.append(currentHFR);
-
- if (focusType == FOCUS_MANUAL || (inAutoFocus && canAbsMove == false && canRelMove == false))
- drawHFRPlot();
- }
- }
-
- // If just framing, let's capture again
- if (inFocusLoop)
- {
- capture();
- return;
- }
-
- //if (starSelected == false)
- if (starCenter.isNull())
- {
- int x=0, y=0, w=0,h=0;
-
- if (frameSettings.contains(targetChip))
- {
- QVariantMap settings = frameSettings[targetChip];
- x = settings["x"].toInt();
- y = settings["y"].toInt();
- w = settings["w"].toInt();
- h = settings["h"].toInt();
- }
- else
- targetChip->getFrame(&x, &y, &w, &h);
-
- if (kcfg_autoSelectStar->isEnabled() && kcfg_autoSelectStar->isChecked() && focusType == FOCUS_AUTO)
- {
- Edge *maxStar = image_data->getMaxHFRStar();
- if (maxStar == NULL)
- {
- appendLogText(i18n("Failed to automatically select a star. Please select a star manually."));
-
- //if (fw == 0 || fh == 0)
- //targetChip->getFrame(&fx, &fy, &fw, &fh);
-
- //targetImage->setTrackingBox(QRect((fw-focusBoxSize->value())/2, (fh-focusBoxSize->value())/2, focusBoxSize->value(), focusBoxSize->value()));
- targetImage->setTrackingBox(QRect(w-focusBoxSize->value()/(subBinX*2), h-focusBoxSize->value()/(subBinY*2), focusBoxSize->value()/subBinX, focusBoxSize->value()/subBinY));
- targetImage->setTrackingBoxEnabled(true);
-
- state = Ekos::FOCUS_WAITING;
- emit newStatus(state);
-
- QTimer::singleShot(AUTO_STAR_TIMEOUT, this, SLOT(checkAutoStarTimeout()));
-
- return;
- }
-
- if (subFramed == false && kcfg_subFrame->isEnabled() && kcfg_subFrame->isChecked())
- {
- int offset = focusBoxSize->value();
- int subX=(maxStar->x - offset) * subBinX;
- int subY=(maxStar->y - offset) * subBinY;
- int subW=offset*2*subBinX;
- int subH=offset*2*subBinY;
-
- int minX, maxX, minY, maxY, minW, maxW, minH, maxH;
- targetChip->getFrameMinMax(&minX, &maxX, &minY, &maxY, &minW, &maxW, &minH, &maxH);
-
- if (subX< minX)
- subX=minX;
- if (subY< minY)
- subY= minY;
- if ((subW+subX)> maxW)
- subW=maxW-subX;
- if ((subH+subY)> maxH)
- subH=maxH-subY;
-
- //targetChip->setFocusFrame(subX, subY, subW, subH);
-
- //fx += subX;
- //fy += subY;
- //fw = subW;
- //fh = subH;
- //frameModified = true;
-
- //x += subX;
- //y += subY;
- //w = subW;
- //h = subH;
-
- QVariantMap settings = frameSettings[targetChip];
- settings["x"] = subX;
- settings["y"] = subY;
- settings["w"] = subW;
- settings["h"] = subH;
- settings["binx"] = subBinX;
- settings["biny"] = subBinY;
-
- frameSettings[targetChip] = settings;
-
- starCenter.setX(subW/(2*subBinX));
- starCenter.setY(subH/(2*subBinY));
-
- subFramed = true;
- }
- else
- {
- starCenter.setX(maxStar->x);
- starCenter.setY(maxStar->y);
- }
-
- starCenter.setZ(subBinX);
- //else
- //targetChip->getFrame(&fx, &fy, &fw, &fh);
-
- //targetImage->setTrackingBox(QRect((w-focusBoxSize->value())/(subBinX*2), (h-focusBoxSize->value())/(subBinY*2), focusBoxSize->value()/subBinX, focusBoxSize->value()/subBinX));
- targetImage->setTrackingBoxEnabled(true);
-
- //starSelected=true;
-
- defaultScale = static_cast<FITSScale>(filterCombo->currentIndex());
-
- capture();
-
- return;
-
-
- }
- else// if (kcfg_subFrame->isEnabled() && kcfg_subFrame->isChecked())
- {
- appendLogText(i18n("Capture complete. Select a star to focus."));
-
- //if (fw == 0 || fh == 0)
- //targetChip->getFrame(&fx, &fy, &fw, &fh);
-
- int subBinX=1,subBinY=1;
- targetChip->getBinning(&subBinX, &subBinY);
-
- targetImage->setTrackingBox(QRect((w-focusBoxSize->value())/(subBinX*2), (h-focusBoxSize->value())/(2*subBinY), focusBoxSize->value()/subBinX, focusBoxSize->value()/subBinY));
- targetImage->setTrackingBoxEnabled(true);
- connect(targetImage, SIGNAL(trackingStarSelected(int,int)), this, SLOT(focusStarSelected(int, int)), Qt::UniqueConnection);
- return;
- }
- }
-
- if (minimumRequiredHFR >= 0)
- {
- if (currentHFR == -1)
- {
- if (noStarCount++ < MAX_RECAPTURE_RETRIES)
- {
- appendLogText(i18n("No stars detected, capturing again..."));
- // On Last Attempt reset focus frame to capture full frame and recapture star if possible
- if (noStarCount == MAX_RECAPTURE_RETRIES)
- resetFrame();
- capture();
- return;
- }
- else
- {
- noStarCount = 0;
- setAutoFocusResult(false);
- }
- }
- else if (currentHFR > minimumRequiredHFR)
- {
- inSequenceFocus = true;
- AutoModeR->setChecked(true);
- start();
- }
- else
- {
- setAutoFocusResult(true);
- }
-
- minimumRequiredHFR = -1;
-
- return;
- }
-
- drawProfilePlot();
-
- if (focusType == FOCUS_MANUAL || inAutoFocus==false)
- return;
-
- if (Options::focusLogging())
- {
- QDir dir;
- QString path = KSPaths::writableLocation(QStandardPaths::GenericDataLocation) + "autofocus/" + QDateTime::currentDateTime().toString("yyyy-MM-dd");
- dir.mkpath(path);
- QString name = "autofocus_frame_" + QDateTime::currentDateTime().toString("HH:mm:ss") + ".fits";
- QString filename = path + QStringLiteral("/") + name;
- targetImage->getImageData()->saveFITS(filename);
- }
-
- if (canAbsMove || canRelMove)
- autoFocusAbs();
- else
- autoFocusRel();
-
-}
-
-void Focus::clearDataPoints()
-{
- maxHFR=1;
- hfr_position.clear();
- hfr_value.clear();
-
- drawHFRPlot();
-}
-
-void Focus::drawHFRPlot()
-{
- v_graph->setData(hfr_position, hfr_value);
-
- if (focusType == FOCUS_AUTO && (canAbsMove || canRelMove) )
- {
- //HFRPlot->xAxis->setLabel(i18n("Position"));
- HFRPlot->xAxis->setRange(minPos-pulseDuration, maxPos+pulseDuration);
- HFRPlot->yAxis->setRange(currentHFR/1.5, maxHFR);
- }
- else
- {
- //HFRPlot->xAxis->setLabel(i18n("Iteration"));
- HFRPlot->xAxis->setRange(1, hfr_value.count()+1);
- HFRPlot->yAxis->setRange(currentHFR/1.5, maxHFR);
- }
-
- HFRPlot->replot();
-
-}
-
-void Focus::drawProfilePlot()
-{
- QVector<double> currentIndexes;
- QVector<double> currentFrequencies;
-
- // HFR = 50% * 1.36 = 68% aka one standard deviation
- double stdDev = currentHFR * 1.36;
- float start= -stdDev*4;
- float end = stdDev*4;
- float step = stdDev*4 / 20.0;
- for (float x=start; x < end; x+= step)
- {
- currentIndexes.append(x);
- currentFrequencies.append((1/(stdDev*sqrt(2*M_PI))) * exp(-1 * ( x*x ) / (2 * (stdDev * stdDev))));
- }
-
- currentGaus->setData(currentIndexes, currentFrequencies);
-
- if (lastGausIndexes.count() > 0)
- lastGaus->setData(lastGausIndexes, lastGausFrequencies);
-
- if (focusType == FOCUS_AUTO && firstGaus == NULL)
- {
- firstGaus = profilePlot->addGraph();
- QPen pen;
- pen.setStyle(Qt::DashDotLine);
- pen.setWidth(2);
- pen.setColor(Qt::darkMagenta);
- firstGaus->setPen(pen);
-
- firstGaus->setData(currentIndexes, currentFrequencies);
- }
- else if (focusType == FOCUS_MANUAL && firstGaus)
- {
- profilePlot->removeGraph(firstGaus);
- firstGaus=NULL;
- }
-
- profilePlot->rescaleAxes();
- profilePlot->replot();
-
- lastGausIndexes = currentIndexes;
- lastGausFrequencies = currentFrequencies;
-
- profilePixmap = profilePlot->grab();
- emit newProfilePixmap(profilePixmap);
-}
-
-void Focus::autoFocusAbs()
-{
- static int lastHFRPos=0, minHFRPos=0, initSlopePos=0, focusOutLimit=0, focusInLimit=0;
- static double minHFR=0, initSlopeHFR=0;
- double targetPosition=0, delta=0;
-
- QString deltaTxt = QString("%1").arg(fabs(currentHFR-minHFR)*100.0, 0,'g', 3);
- QString HFRText = QString("%1").arg(currentHFR, 0,'g', 3);
-
- if (Options::focusLogging())
- {
- qDebug() << "Focus: ########################################";
- qDebug() << "Focus: ========================================";
- qDebug() << "Focus: Current HFR: " << currentHFR << " Current Position: " << currentPosition;
- qDebug() << "Focus: Last minHFR: " << minHFR << " Last MinHFR Pos: " << minHFRPos;
- qDebug() << "Focus: Delta: " << deltaTxt << "%";
- qDebug() << "Focus: ========================================";
- }
-
- if (minHFR)
- appendLogText(i18n("FITS received. HFR %1 @ %2. Delta (%3%)", HFRText, currentPosition, deltaTxt));
- else
- appendLogText(i18n("FITS received. HFR %1 @ %2.", HFRText, currentPosition));
-
- if (++absIterations > MAXIMUM_ABS_ITERATIONS)
- {
- appendLogText(i18n("Autofocus failed to reach proper focus. Try increasing tolerance value."));
- abort();
- setAutoFocusResult(false);
- return;
- }
-
- // No stars detected, try to capture again
- if (currentHFR == -1)
- {
- if (noStarCount < MAX_RECAPTURE_RETRIES)
- {
- appendLogText(i18n("No stars detected, capturing again..."));
- capture();
- noStarCount++;
- return;
- }
- else if (noStarCount == MAX_RECAPTURE_RETRIES)
- {
- currentHFR = 20;
- noStarCount++;
- }
- else
- {
- appendLogText(i18n("Failed to detect any stars. Reset frame and try again."));
- abort();
- setAutoFocusResult(false);
- return;
- }
- }
- else
- noStarCount = 0;
-
- /*if (currentHFR > maxHFR || HFRAbsolutePoints.empty())
- {
- maxHFR = currentHFR;
-
- if (HFRAbsolutePoints.empty())
- {
- maxPos=1;
- minPos=1e6;
- }
- }*/
-
- if (hfr_position.empty())
- {
- maxPos=1;
- minPos=1e6;
- }
-
- if (currentPosition > maxPos)
- maxPos = currentPosition;
- if (currentPosition < minPos)
- minPos = currentPosition;
-
- //HFRPoint *p = new HFRPoint();
-
- //p->HFR = currentHFR;
- //p->pos = currentPosition;
-
- hfr_position.append(currentPosition);
- hfr_value.append(currentHFR);
-
- //HFRAbsolutePoints.append(p);
-
- drawHFRPlot();
-
- switch (lastFocusDirection)
- {
- case FOCUS_NONE:
- lastHFR = currentHFR;
- initialFocuserAbsPosition = currentPosition;
- minHFR=currentHFR;
- minHFRPos=currentPosition;
- HFRDec=0;
- HFRInc=0;
- focusOutLimit=0;
- focusInLimit=0;
- FocusOut(pulseDuration);
- break;
-
- case FOCUS_IN:
- case FOCUS_OUT:
- if (reverseDir && focusInLimit && focusOutLimit && fabs(currentHFR - minHFR) < (toleranceIN->value()/100.0) && HFRInc == 0 )
- {
- if (absIterations <= 2)
- {
- appendLogText(i18n("Change in HFR is too small. Try increasing the step size or decreasing the tolerance."));
- abort();
- setAutoFocusResult(false);
- }
- else if (noStarCount > 0)
- {
- appendLogText(i18n("Failed to detect focus star in frame. Capture and select a focus star."));
- abort();
- setAutoFocusResult(false);
- }
- else
- {
- appendLogText(i18n("Autofocus complete."));
- abort();
- emit suspendGuiding(false);
- setAutoFocusResult(true);
- }
- break;
- }
- else if (currentHFR < lastHFR)
- {
- double slope=0;
-
- // Let's try to calculate slope of the V curve.
- if (initSlopeHFR == 0 && HFRInc == 0 && HFRDec >= 1)
- {
- initSlopeHFR = lastHFR;
- initSlopePos = lastHFRPos;
-
- if (Options::focusLogging())
- qDebug() << "Focus: Setting initial slop to " << initSlopePos << " @ HFR " << initSlopeHFR;
- }
-
- // Let's now limit the travel distance of the focuser
- if (lastFocusDirection == FOCUS_OUT && lastHFRPos < focusInLimit && fabs(currentHFR - lastHFR) > 0.1)
- {
- focusInLimit = lastHFRPos;
- if (Options::focusLogging())
- qDebug() << "Focus: New FocusInLimit " << focusInLimit;
- }
- else if (lastFocusDirection == FOCUS_IN && lastHFRPos > focusOutLimit && fabs(currentHFR - lastHFR) > 0.1)
- {
- focusOutLimit = lastHFRPos;
- if (Options::focusLogging())
- qDebug() << "Focus: New FocusOutLimit " << focusOutLimit;
- }
-
- // If we have slope, get next target position
- if (initSlopeHFR && absMotionMax > 50)
- {
- double factor=0.5;
- slope = (currentHFR - initSlopeHFR) / (currentPosition - initSlopePos);
- if (fabs(currentHFR-minHFR)*100.0 < 0.5)
- factor = 1 - fabs(currentHFR-minHFR)*10;
- targetPosition = currentPosition + (currentHFR*factor - currentHFR)/slope;
- if (targetPosition < 0)
- {
- factor = 1;
- while (targetPosition < 0 && factor > 0)
- {
- factor -= 0.005;
- targetPosition = currentPosition + (currentHFR*factor - currentHFR)/slope;
- }
- }
- if (Options::focusLogging())
- qDebug() << "Focus: Using slope to calculate target pulse...";
- }
- // Otherwise proceed iteratively
- else
- {
- if (lastFocusDirection == FOCUS_IN)
- targetPosition = currentPosition - pulseDuration;
- else
- targetPosition = currentPosition + pulseDuration;
-
- if (Options::focusLogging())
- qDebug() << "Focus: Proceeding iteratively to next target pulse ...";
- }
-
- if (Options::focusLogging())
- qDebug() << "Focus: V-Curve Slope " << slope << " current Position " << currentPosition << " targetPosition " << targetPosition;
-
- lastHFR = currentHFR;
-
- // Let's keep track of the minimum HFR
- if (lastHFR < minHFR)
- {
- minHFR = lastHFR;
- minHFRPos = currentPosition;
- if (Options::focusLogging())
- {
- qDebug() << "Focus: new minHFR " << minHFR << " @ positioin " << minHFRPos;
- qDebug() << "Focus: ########################################";
- }
-
- }
-
- lastHFRPos = currentPosition;
-
- // HFR is decreasing, we are on the right direction
- HFRDec++;
- HFRInc=0;
- }
- else
-
- {
- // HFR increased, let's deal with it.
- HFRInc++;
- HFRDec=0;
-
- // Reality Check: If it's first time, let's capture again and see if it changes.
- /*if (HFRInc <= 1 && reverseDir == false)
- {
- capture();
- return;
- }
- // Looks like we're going away from optimal HFR
- else
- {*/
- reverseDir = true;
- lastHFR = currentHFR;
- lastHFRPos = currentPosition;
- initSlopeHFR=0;
- HFRInc=0;
-
- if (Options::focusLogging())
- qDebug() << "Focus: We are going away from optimal HFR ";
-
- // Let's set new limits
- if (lastFocusDirection == FOCUS_IN)
- {
- focusInLimit = currentPosition;
- if (Options::focusLogging())
- qDebug() << "Focus: Setting focus IN limit to " << focusInLimit;
- }
- else
- {
- focusOutLimit = currentPosition;
- if (Options::focusLogging())
- qDebug() << "Focus: Setting focus OUT limit to " << focusOutLimit;
- }
-
- // Decrease pulse
- pulseDuration = pulseDuration * 0.75;
-
- // Let's get close to the minimum HFR position so far detected
- if (lastFocusDirection == FOCUS_OUT)
- targetPosition = minHFRPos-pulseDuration/2;
- else
- targetPosition = minHFRPos+pulseDuration/2;
-
- if (Options::focusLogging())
- qDebug() << "Focus: new targetPosition " << targetPosition;
-
- // }
- }
-
- // Limit target Pulse to algorithm limits
- if (focusInLimit != 0 && lastFocusDirection == FOCUS_IN && targetPosition < focusInLimit)
- {
- targetPosition = focusInLimit;
- if (Options::focusLogging())
- qDebug() << "Focus: Limiting target pulse to focus in limit " << targetPosition;
- }
- else if (focusOutLimit != 0 && lastFocusDirection == FOCUS_OUT && targetPosition > focusOutLimit)
- {
- targetPosition = focusOutLimit;
- if (Options::focusLogging())
- qDebug() << "Focus: Limiting target pulse to focus out limit " << targetPosition;
- }
-
- // Limit target pulse to focuser limits
- if (targetPosition < absMotionMin)
- targetPosition = absMotionMin;
- else if (targetPosition > absMotionMax)
- targetPosition = absMotionMax;
-
- // Ops, we can't go any further, we're done.
- if (targetPosition == currentPosition)
- {
- appendLogText(i18n("Autofocus complete."));
- abort();
- emit suspendGuiding(false);
- setAutoFocusResult(true);
- return;
- }
-
- // Ops, deadlock
- if (focusOutLimit && focusOutLimit == focusInLimit)
- {
- appendLogText(i18n("Deadlock reached. Please try again with different settings."));
- abort();
- setAutoFocusResult(false);
- return;
- }
-
- if (fabs(targetPosition - initialFocuserAbsPosition) > maxTravelIN->value())
- {
- if (Options::focusLogging())
- qDebug() << "Focus: targetPosition (" << targetPosition << ") - initHFRAbsPos (" << initialFocuserAbsPosition << ") exceeds maxTravel distance of " << maxTravelIN->value();
-
- appendLogText("Maximum travel limit reached. Autofocus aborted.");
- abort();
- setAutoFocusResult(false);
- break;
-
- }
-
- // Get delta for next move
- delta = (targetPosition - currentPosition);
-
- if (Options::focusLogging())
- {
- qDebug() << "Focus: delta (targetPosition - currentPosition) " << delta;
- qDebug() << "Focus: Focusing " << ((delta < 0) ? "IN" : "OUT");
- qDebug() << "Focus: ########################################";
- }
-
- // Now cross your fingers and wait
- if (delta > 0)
- FocusOut(delta);
- else
- FocusIn(fabs(delta));
- break;
-
- }
-
-}
-
-void Focus::autoFocusRel()
-{
- static int noStarCount=0;
- static double minHFR=1e6;
- QString deltaTxt = QString("%1").arg(fabs(currentHFR-minHFR)*100.0, 0,'g', 2);
- QString minHFRText = QString("%1").arg(minHFR, 0, 'g', 3);
- QString HFRText = QString("%1").arg(currentHFR, 0,'g', 3);
-
- appendLogText(i18n("FITS received. HFR %1. Delta (%2%) Min HFR (%3)", HFRText, deltaTxt, minHFRText));
-
- if (pulseDuration <= MINIMUM_PULSE_TIMER)
- {
- appendLogText(i18n("Autofocus failed to reach proper focus. Try adjusting the tolerance value."));
- abort();
- setAutoFocusResult(false);
- return;
- }
-
- // No stars detected, try to capture again
- if (currentHFR == -1)
- {
- if (noStarCount++ < MAX_RECAPTURE_RETRIES)
- {
- appendLogText(i18n("No stars detected, capturing again..."));
- capture();
- return;
- }
- else
- currentHFR = 20;
- }
- else
- noStarCount = 0;
-
- switch (lastFocusDirection)
- {
- case FOCUS_NONE:
- lastHFR = currentHFR;
- minHFR=1e6;
- FocusIn(pulseDuration);
- break;
-
- case FOCUS_IN:
- //if (fabs(currentHFR - lastHFR) < (toleranceIN->value()/100.0) && HFRInc == 0)
- if (fabs(currentHFR - minHFR) < (toleranceIN->value()/100.0) && HFRInc == 0)
- {
- appendLogText(i18n("Autofocus complete."));
- abort();
- emit suspendGuiding(false);
- setAutoFocusResult(true);
- break;
- }
- else if (currentHFR < lastHFR)
- {
- if (currentHFR < minHFR)
- minHFR = currentHFR;
-
- lastHFR = currentHFR;
- FocusIn(pulseDuration);
- HFRInc=0;
- }
- else
- {
- HFRInc++;
-
- /*if (HFRInc <= 1)
- {
- capture();
- return;
- }
- else
- {*/
-
- lastHFR = currentHFR;
-
- HFRInc=0;
-
- pulseDuration *= 0.75;
- FocusOut(pulseDuration);
- //}
- }
-
- break;
-
- case FOCUS_OUT:
- if (fabs(currentHFR - minHFR) < (toleranceIN->value()/100.0) && HFRInc == 0)
- //if (fabs(currentHFR - lastHFR) < (toleranceIN->value()/100.0) && HFRInc == 0)
- {
- appendLogText(i18n("Autofocus complete."));
- abort();
- emit suspendGuiding(false);
- setAutoFocusResult(true);
- break;
- }
- else if (currentHFR < lastHFR)
- {
- if (currentHFR < minHFR)
- minHFR = currentHFR;
-
- lastHFR = currentHFR;
- FocusOut(pulseDuration);
- HFRInc=0;
- }
- else
- {
- HFRInc++;
-
- /*if (HFRInc <= 1)
- capture();
- else
- {*/
-
- lastHFR = currentHFR;
-
- HFRInc=0;
-
- pulseDuration *= 0.75;
- FocusIn(pulseDuration);
- //}
- }
-
- break;
-
- }
-
-}
-
-void Focus::processFocusNumber(INumberVectorProperty *nvp)
-{
-
- if (canAbsMove == false && currentFocuser->canAbsMove())
- {
- canAbsMove = true;
- getAbsFocusPosition();
-
- absTicksSpin->setEnabled(true);
- setAbsTicksB->setEnabled(true);
- }
-
- if (canRelMove == false && currentFocuser->canRelMove())
- canRelMove = true;
-
- if (!strcmp(nvp->name, "ABS_FOCUS_POSITION"))
- {
- INumber *pos = IUFindNumber(nvp, "FOCUS_ABSOLUTE_POSITION");
- if (pos)
- {
- currentPosition = pos->value;
- absTicksSpin->setValue(currentPosition);
- }
-
- if (resetFocus && nvp->s == IPS_OK)
- {
- resetFocus = false;
- appendLogText(i18n("Restarting autofocus process..."));
- start();
- }
-
- if (canAbsMove && inAutoFocus)
- {
- if (nvp->s == IPS_OK && captureInProgress == false)
- capture();
- else if (nvp->s == IPS_ALERT)
- {
- appendLogText(i18n("Focuser error, check INDI panel."));
- abort();
- setAutoFocusResult(false);
- }
-
- }
-
- return;
- }
-
- if (canAbsMove)
- return;
-
- if (!strcmp(nvp->name, "REL_FOCUS_POSITION"))
- {
- INumber *pos = IUFindNumber(nvp, "FOCUS_RELATIVE_POSITION");
- if (pos && nvp->s == IPS_OK)
- currentPosition += pos->value * (lastFocusDirection == FOCUS_IN ? -1 : 1);
-
- if (resetFocus && nvp->s == IPS_OK)
- {
- resetFocus = false;
- appendLogText(i18n("Restarting autofocus process..."));
- start();
- }
-
- if (canRelMove && inAutoFocus)
- {
- if (nvp->s == IPS_OK && captureInProgress == false)
- capture();
- else if (nvp->s == IPS_ALERT)
- {
- appendLogText(i18n("Focuser error, check INDI panel."));
- abort();
- setAutoFocusResult(false);
- }
- }
-
- return;
- }
-
- if (canRelMove)
- return;
-
- if (!strcmp(nvp->name, "FOCUS_TIMER"))
- {
- if (resetFocus && nvp->s == IPS_OK)
- {
- resetFocus = false;
- appendLogText(i18n("Restarting autofocus process..."));
- start();
- }
-
- if (canAbsMove == false && canRelMove == false && inAutoFocus)
- {
- if (nvp->s == IPS_OK && captureInProgress == false)
- capture();
- else if (nvp->s == IPS_ALERT)
- {
- appendLogText(i18n("Focuser error, check INDI panel."));
- abort();
- setAutoFocusResult(false);
- }
-
- }
-
- return;
- }
-
-}
-
-void Focus::appendLogText(const QString &text)
-{
-
- logText.insert(0, i18nc("log entry; %1 is the date, %2 is the text", "%1 %2", QDateTime::currentDateTime().toString("yyyy-MM-ddThh:mm:ss"), text));
-
- if (Options::focusLogging())
- qDebug() << "Focus: " << text;
-
- emit newLog();
-}
-
-void Focus::clearLog()
-{
- logText.clear();
- emit newLog();
-}
-
-void Focus::startFraming()
-{
- if (currentCCD == NULL)
- {
- appendLogText(i18n("No CCD connected."));
- return;
- }
-
- inFocusLoop = true;
- frameNum=0;
-
- //emit statusUpdated(true);
- state = Ekos::FOCUS_FRAMING;
- emit newStatus(state);
-
- resetButtons();
-
- appendLogText(i18n("Starting continuous exposure..."));
-
- capture();
-}
-
-void Focus::resetButtons()
-{
-
- if (inFocusLoop)
- {
- startFocusB->setEnabled(false);
- startLoopB->setEnabled(false);
- stopFocusB->setEnabled(true);
-
- captureB->setEnabled(false);
- focusOutB->setEnabled(true);
- focusInB->setEnabled(true);
-
- return;
- }
-
- if (inAutoFocus)
- {
- stopFocusB->setEnabled(true);
-
- startFocusB->setEnabled(false);
- startLoopB->setEnabled(false);
- captureB->setEnabled(false);
- focusOutB->setEnabled(false);
- focusInB->setEnabled(false);
-
- return;
- }
-
- if (focusType == FOCUS_AUTO && currentFocuser)
- startFocusB->setEnabled(true);
- else
- startFocusB->setEnabled(false);
-
- stopFocusB->setEnabled(false);
- startLoopB->setEnabled(true);
-
-
- if (focusType == FOCUS_MANUAL)
- {
- if (currentFocuser)
- {
- focusOutB->setEnabled(true);
- focusInB->setEnabled(true);
- }
-
- startLoopB->setEnabled(true);
- }
- else
- {
- focusOutB->setEnabled(false);
- focusInB->setEnabled(false);
- }
-
- captureB->setEnabled(true);
-}
-
-void Focus::updateBoxSize(int value)
-{
- ISD::CCDChip *targetChip = currentCCD->getChip(ISD::CCDChip::PRIMARY_CCD);
- if (targetChip == NULL)
- return;
-
- FITSView *targetImage = targetChip->getImage(FITS_FOCUS);
- if (targetImage == NULL)
- return;
-
- QRect trackBox = targetImage->getTrackingBox();
- trackBox.setX(trackBox.x()+(trackBox.width()-value)/2);
- trackBox.setY(trackBox.y()+(trackBox.height()-value)/2);
- trackBox.setWidth(value);
- trackBox.setHeight(value);
-
- targetImage->setTrackingBox(trackBox);
-}
-
-void Focus::focusStarSelected(int x, int y)
-{
- if (state == Ekos::FOCUS_PROGRESS)
- return;
-
- ISD::CCDChip *targetChip = currentCCD->getChip(ISD::CCDChip::PRIMARY_CCD);
-
- int subBinX, subBinY;
- targetChip->getBinning(&subBinX, &subBinY);
-
- // If binning was changed outside of the focus module, recapture
- if (subBinX != activeBin)
- {
- capture();
- return;
- }
-
- int offset = focusBoxSize->value()/subBinX;
-
- FITSView *targetImage = targetChip->getImage(FITS_FOCUS);
-
- //targetImage->updateMode(FITS_FOCUS);
-
- QRect starRect;
-
- if (subFramed == false && kcfg_subFrame->isChecked() && targetChip->canSubframe())
- {
- int minX, maxX, minY, maxY, minW, maxW, minH, maxH;//, fx,fy,fw,fh;
-
- targetChip->getFrameMinMax(&minX, &maxX, &minY, &maxY, &minW, &maxW, &minH, &maxH);
- //targetChip->getFrame(&fx, &fy, &fw, &fy);
-
- x = (x - offset) * subBinX;
- y = (y - offset) * subBinY;
- int w=offset*2*subBinX;
- int h=offset*2*subBinY;
-
- if (x<minX)
- x=minX;
- if (y<minY)
- y=minY;
- if ((x+w)>maxW)
- w=maxW-x;
- if ((y+h)>maxH)
- h=maxH-y;
-
- //targetChip->getFrame(&orig_x, &orig_y, &orig_w, &orig_h);
-
- //fx += x;
- //fy += y;
- //fw = w;
- //fh = h;
-
- //targetChip->setFocusFrame(fx, fy, fw, fh);
- //frameModified=true;
-
- QVariantMap settings = frameSettings[targetChip];
- settings["x"] = x;
- settings["y"] = y;
- settings["w"] = w;
- settings["h"] = h;
- settings["binx"] = subBinX;
- settings["biny"] = subBinY;
-
- frameSettings[targetChip] = settings;
-
- subFramed = true;
-
- capture();
-
- //starRect = QRect((w-focusBoxSize->value())/(subBinX*2), (h-focusBoxSize->value())/(subBinY*2), focusBoxSize->value()/subBinX, focusBoxSize->value()/subBinY);
- starCenter.setX(w/(2*subBinX));
- starCenter.setY(h/(2*subBinY));
- }
- else
- {
- //starRect = QRect(x-focusBoxSize->value()/(subBinX*2), y-focusBoxSize->value()/(subBinY*2), focusBoxSize->value()/subBinX, focusBoxSize->value()/subBinY);
- starCenter.setX(x);
- starCenter.setY(y);
- starRect = QRect( starCenter.x()-focusBoxSize->value()/(2*subBinX), starCenter.y()-focusBoxSize->value()/(2*subBinY), focusBoxSize->value()/subBinX, focusBoxSize->value()/subBinY);
- targetImage->setTrackingBox(starRect);
- }
-
- starCenter.setZ(subBinX);
-
- //starSelected=true;
-
- defaultScale = static_cast<FITSScale>(filterCombo->currentIndex());
-
- //targetImage->setTrackingBox(starRect);
-}
-
-void Focus::checkFocus(double requiredHFR)
-{
- minimumRequiredHFR = requiredHFR;
-
- capture();
-}
-
-void Focus::toggleSubframe(bool enable)
-{
- if (enable == false)
- {
- resetFrame();
- kcfg_autoSelectStar->setChecked(false);
- }
-
- //starSelected = false;
- starCenter = QVector3D();
-}
-
-void Focus::filterChangeWarning(int index)
-{
- // index = 4 is MEDIAN filter which helps reduce noise
- if (index != 0 && index != FITS_MEDIAN)
- appendLogText(i18n("Warning: Only use filters for preview as they may interface with autofocus operation."));
-
- Options::setFocusEffect(index);
-
- defaultScale = static_cast<FITSScale>(index);
-}
-
-void Focus::setExposure(double value)
-{
- exposureIN->setValue(value);
-}
-
-void Focus::setBinning(int subBinX, int subBinY)
-{
- INDI_UNUSED(subBinY);
- binningCombo->setCurrentIndex(subBinX-1);
-}
-
-void Focus::setImageFilter(const QString & value)
-{
- for (int i=0; i < filterCombo->count(); i++)
- if (filterCombo->itemText(i) == value)
- {
- filterCombo->setCurrentIndex(i);
- break;
- }
-}
-
-void Focus::setAutoFocusStar(bool enable)
-{
- kcfg_autoSelectStar->setChecked(enable);
-}
-
-void Focus::setAutoFocusSubFrame(bool enable)
-{
- kcfg_subFrame->setChecked(enable);
-}
-
-void Focus::setAutoFocusParameters(int boxSize, int stepSize, int maxTravel, double tolerance)
-{
- focusBoxSize->setValue(boxSize);
- stepIN->setValue(stepSize);
- maxTravelIN->setValue(maxTravel);
- toleranceIN->setValue(tolerance);
-}
-
-bool Focus::setFocusMode(int mode)
-{
- // If either of them is disabled, return false
- if ( (mode == 0 && manualModeR->isEnabled() == false) || (mode == 1 && AutoModeR->isEnabled() == false) )
- return false;
-
- if (mode == 0)
- manualModeR->setChecked(true);
- else
- AutoModeR->setChecked(true);
-
- checkCCD();
-
- return true;
-}
-
-void Focus::setAutoFocusResult(bool status)
-{
- m_autoFocusSuccesful = status;
-
- // In case of failure, go back to last position if the focuser is absolute
- if (status == false && canAbsMove && currentFocuser && initialFocuserAbsPosition >= 0)
- {
- currentFocuser->moveAbs(initialFocuserAbsPosition);
- appendLogText(i18n("Autofocus failed, moving back to initial focus position %1.", initialFocuserAbsPosition));
-
- // If we're doing in sequence focusing using an absolute focuser, let's retry focusing starting from last known good position before we give up
- if (inSequenceFocus && resetFocusIteration++ < MAXIMUM_RESET_ITERATIONS && resetFocus == false)
- {
- resetFocus = true;
- // Reset focus frame in case the star in subframe was lost
- resetFrame();
- return;
- }
- }
-
- resetFocusIteration = 0;
-
- //emit autoFocusFinished(status, currentHFR);
-
- if (status)
- {
- KNotification::event( QLatin1String( "FocusSuccessful" ) , i18n("Autofocus operation completed successfully"));
- state = Ekos::FOCUS_COMPLETE;
- }
- else
- {
- KNotification::event( QLatin1String( "FocusFailed" ) , i18n("Autofocus operation failed with errors"));
- state = Ekos::FOCUS_FAILED;
- }
-
- emit newStatus(state);
-}
-
-void Focus::checkAutoStarTimeout()
-{
- //if (starSelected == false && inAutoFocus)
- if (starCenter.isNull() && inAutoFocus)
- {
- appendLogText(i18n("No star was selected. Aborting..."));
- initialFocuserAbsPosition=-1;
- abort();
- setAutoFocusResult(false);
- }
-}
-
-void Focus::setAbsoluteFocusTicks()
-{
- if (currentFocuser == NULL)
- return;
-
- if (currentFocuser->isConnected() == false)
- {
- appendLogText(i18n("Error: Lost connection to Focuser."));
- return;
- }
-
- if (Options::focusLogging())
- qDebug() << "Focus: Setting focus ticks to " << absTicksSpin->value();
-
- currentFocuser->moveAbs(absTicksSpin->value());
-}
-
-void Focus::setActiveBinning(int bin)
-{
- activeBin = bin + 1;
-}
-
-void Focus::setThreshold(double value)
-{
- Options::setFocusThreshold(value);
-}
-
-void Focus::setFrames(int value)
-{
- Options::setFocusFrames(value);
-}
-
-}
-
-
diff --git a/kstars/ekos/focus.h b/kstars/ekos/focus.h
deleted file mode 100644
index 065f3b1..0000000
--- a/kstars/ekos/focus.h
+++ /dev/null
@@ -1,483 +0,0 @@
-/* Ekos Focus tool
- Copyright (C) 2012 Jasem Mutlaq <mutlaqja@ikarustech.com>
-
- This application is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
- */
-
-#ifndef FOCUS_H
-#define FOCUS_H
-
-#include <QtDBus/QtDBus>
-
-#include "focus.h"
-#include "capture.h"
-
-#include "ui_focus.h"
-
-#include "indi/indistd.h"
-#include "indi/indifocuser.h"
-
-
-namespace Ekos
-{
-
-struct HFRPoint
-{
- int pos;
- double HFR;
-};
-
-/**
- *@class Focus
- *@short Supports manual focusing and auto focusing using relative and absolute INDI focusers.
- *@author Jasem Mutlaq
- *@version 1.1
- */
-class Focus : public QWidget, public Ui::Focus
-{
-
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.Ekos.Focus")
-
-public:
- Focus();
- ~Focus();
-
- typedef enum { FOCUS_NONE, FOCUS_IN, FOCUS_OUT } FocusDirection;
- typedef enum { FOCUS_MANUAL, FOCUS_AUTO, FOCUS_LOOP } FocusType;
-
- /** @defgroup FocusDBusInterface Ekos DBus Interface - Focus Module
- * Ekos::Focus interface provides advanced scripting capabilities to perform manual and automatic focusing operations.
- */
-
- /*@{*/
-
- /** DBUS interface function.
- * select the CCD device from the available CCD drivers.
- * @param device The CCD device name
- * @return Returns true if CCD device is found and set, false otherwise.
- */
- Q_SCRIPTABLE bool setCCD(QString device);
-
- /** DBUS interface function.
- * select the focuser device from the available focuser drivers. The focuser device can be the same as the CCD driver if the focuser functionality was embedded within the driver.
- * @param device The focuser device name
- * @return Returns true if focuser device is found and set, false otherwise.
- */
- Q_SCRIPTABLE bool setFocuser(QString device);
-
- /** DBUS interface function.
- * select the filter device from the available filter drivers. The filter device can be the same as the CCD driver if the filter functionality was embedded within the driver.
- * @param device The filter device name
- * @return Returns true if filter device is found and set, false otherwise.
- */
- Q_SCRIPTABLE bool setFilter(QString device, int filterSlot);
-
- /** DBUS interface function.
- * @return Returns true if autofocus operation is complete. False otherwise.
- */
- Q_SCRIPTABLE bool isAutoFocusComplete() { return (inAutoFocus == false);}
-
- /** DBUS interface function.
- * @return Returns true if autofocus operation is successful. False otherwise.
- */
- Q_SCRIPTABLE bool isAutoFocusSuccessful() { return m_autoFocusSuccesful;}
-
- /** DBUS interface function.
- * @return Returns Half-Flux-Radius in pixels.
- */
- Q_SCRIPTABLE double getHFR() { return currentHFR; }
-
- /** DBUS interface function.
- * Set Focus mode (Manual or Auto)
- * @param mode 0 for manual, any other value for auto.
- */
- Q_SCRIPTABLE bool setFocusMode(int mode);
-
- /** DBUS interface function.
- * Set CCD exposure value
- * @param value exposure value in seconds.
- */
- Q_SCRIPTABLE Q_NOREPLY void setExposure(double value);
-
- /** DBUS interface function.
- * Set CCD binning
- * @param binX horizontal binning
- * @param binY vertical binning
- */
- Q_SCRIPTABLE Q_NOREPLY void setBinning(int binX, int binY);
-
- /** DBUS interface function.
- * Set image filter to apply to the image after capture.
- * @param value Image filter (Auto Stretch, High Contrast, Equalize, High Pass)
- */
- Q_SCRIPTABLE Q_NOREPLY void setImageFilter(const QString & value);
-
- /** DBUS interface function.
- * Set Auto Focus options. The options must be set before starting the autofocus operation. If no options are set, the options loaded from the user configuration are used.
- * @param enable If true, Ekos will attempt to automatically select the best focus star in the frame. If it fails to select a star, the user will be asked to select a star manually.
- */
- Q_SCRIPTABLE Q_NOREPLY void setAutoFocusStar(bool enable);
-
-
- /** DBUS interface function.
- * Set Auto Focus options. The options must be set before starting the autofocus operation. If no options are set, the options loaded from the user configuration are used.
- * @param enable if true, Ekos will capture a subframe around the selected focus star. The subframe size is determined by the boxSize parameter.
- */
- Q_SCRIPTABLE Q_NOREPLY void setAutoFocusSubFrame(bool enable);
-
- /** DBUS interface function.
- * Set Autofocus parameters
- * @param boxSize the box size around the focus star in pixels. The boxsize is used to subframe around the focus star.
- * @param stepSize the initial step size to be commanded to the focuser. If the focuser is absolute, the step size is in ticks. For relative focusers, the focuser will be commanded to focus inward for stepSize milliseconds initially.
- * @param maxTravel the maximum steps permitted before the autofocus operation aborts.
- * @param tolerance Measure of how accurate the autofocus algorithm is. If the difference between the current HFR and minimum measured HFR is less than %tolerance after the focuser traversed both ends of the V-curve, then the focusing operation
- * is deemed successful. Otherwise, the focusing operation will continue.
- */
- Q_SCRIPTABLE Q_NOREPLY void setAutoFocusParameters(int boxSize, int stepSize, int maxTravel, double tolerance);
-
- /** DBUS interface function.
- * resetFrame Resets the CCD frame to its full native resolution.
- */
- Q_SCRIPTABLE Q_NOREPLY void resetFrame();
-
- /** @}*/
-
- /**
- * @brief Add CCD to the list of available CCD.
- * @param newCCD pointer to CCD device.
- */
- void addCCD(ISD::GDInterface *newCCD);
-
- /**
- * @brief addFocuser Add focuser to the list of available focusers.
- * @param newFocuser pointer to focuser device.
- */
- void addFocuser(ISD::GDInterface *newFocuser);
-
- /**
- * @brief addFilter Add filter to the list of available filters.
- * @param newFilter pointer to filter device.
- */
- void addFilter(ISD::GDInterface *newFilter);
-
-
- void clearLog();
- QString getLogText() { return logText.join("\n"); }
-
-public slots:
-
- /** \addtogroup FocusDBusInterface
- * @{
- */
-
- /* Focus */
- /** DBUS interface function.
- * Start the autofocus operation.
- */
- Q_SCRIPTABLE Q_NOREPLY void start();
-
- /** DBUS interface function.
- * Abort the autofocus operation.
- */
- Q_SCRIPTABLE Q_NOREPLY void abort();
-
- /** DBUS interface function.
- * Capture a focus frame.
- */
- Q_SCRIPTABLE Q_NOREPLY void capture();
-
- /** DBUS interface function.
- * Focus inward
- * @param ms If set, focus inward for ms ticks (Absolute Focuser), or ms milliseconds (Relative Focuser). If not set, it will use the value specified in the options.
- */
- Q_SCRIPTABLE Q_NOREPLY void FocusIn(int ms=-1);
-
- /** DBUS interface function.
- * Focus outward
- * @param ms If set, focus outward for ms ticks (Absolute Focuser), or ms milliseconds (Relative Focuser). If not set, it will use the value specified in the options.
- */
- Q_SCRIPTABLE Q_NOREPLY void FocusOut(int ms=-1);
-
- /** @}*/
-
- /**
- * @brief startFraming Begins continious capture of the CCD and calculates HFR every frame.
- */
- void startFraming();
-
- /**
- * @brief checkStopFocus Perform checks before stopping the autofocus operation. Some checks are necessary for in-sequence focusing.
- */
- void checkStopFocus();
-
- /**
- * @brief Check CCD and make sure information is updated accordingly. This simply calls syncCCDInfo for the current CCD.
- * @param CCDNum By default, we check the already selected CCD in the dropdown menu. If CCDNum is specified, the check is made against this specific CCD in the dropdown menu.
- * CCDNum is the index of the CCD in the dropdown menu.
- */
- void checkCCD(int CCDNum=-1);
-
- /**
- * @brief syncCCDInfo Read current CCD information and update settings accordingly.
- */
- void syncCCDInfo();
-
- /**
- * @brief Check Focuser and make sure information is updated accordingly.
- * @param FocuserNum By default, we check the already selected focuser in the dropdown menu. If FocuserNum is specified, the check is made against this specific focuser in the dropdown menu.
- * FocuserNum is the index of the focuser in the dropdown menu.
- */
- void checkFocuser(int FocuserNum=-1);
-
- /**
- * @brief Check Filter and make sure information is updated accordingly.
- * @param filterNum By default, we check the already selected filter in the dropdown menu. If filterNum is specified, the check is made against this specific filter in the dropdown menu.
- * filterNum is the index of the filter in the dropdown menu.
- */
- void checkFilter(int filterNum=-1);
-
-
- /**
- * @brief clearDataPoints Remove all data points from HFR plots
- */
- void clearDataPoints();
-
- /**
- * @brief focusStarSelected The user selected a focus star, save its coordinates and subframe it if subframing is enabled.
- * @param x X coordinate
- * @param y Y coordinate
- */
- void focusStarSelected(int x, int y);
-
- /**
- * @brief newFITS A new FITS blob is received by the CCD driver.
- * @param bp pointer to blob data
- */
- void newFITS(IBLOB *bp);
-
- /**
- * @brief processFocusNumber Read focus number properties of interest as they arrive from the focuser driver and process them accordingly.
- * @param nvp pointer to updated focuser number property.
- */
- void processFocusNumber(INumberVectorProperty *nvp);
-
- /**
- * @brief checkFocus Given the minimum required HFR, check focus and calculate HFR. If current HFR exceeds required HFR, start autofocus process, otherwise do nothing.
- * @param requiredHFR Minimum HFR to trigger autofocus process.
- */
- void checkFocus(double requiredHFR);
-
- /**
- * @brief setFocusStatus Upon completion of the focusing process, set its status (fail or pass) and reset focus process to clean state.
- * @param status If true, the focus process finished successfully. Otherwise, it failed.
- */
- void setAutoFocusResult(bool status);
-
- /**
- * @brief filterChangeWarning Warn the user it is not a good idea to apply image filter in the filter process as they can skew the HFR calculations.
- * @param index Index of image filter selected by the user.
- */
- void filterChangeWarning(int index);
-
- // Log
- void appendLogText(const QString &);
-
-private slots:
- /**
- * @brief filterLockToggled Process filter locking/unlocking. Filter lock causes the autofocus process to use the selected filter whenever it runs.
- */
- void filterLockToggled(bool);
-
- /**
- * @brief updateFilterPos If filter locking is checked, set the locked filter to the current filter position
- * @param index current filter position
- */
- void updateFilterPos(int index);
-
- /**
- * @brief toggleAutofocus Process switching between manual and automated focus.
- * @param enable If true, auto focus is selected, if false, manual mode is selected.
- */
- void toggleAutofocus(bool enable);
-
- /**
- * @brief toggleSubframe Process enabling and disabling subframing.
- * @param enable If true, subframing is enabled. If false, subframing is disabled. Even if subframing is enabled, it must be supported by the CCD driver.
- */
- void toggleSubframe(bool enable);
-
- void checkAutoStarTimeout();
-
- void setAbsoluteFocusTicks();
-
- void setActiveBinning(int bin);
-
- void setDefaultCCD(QString ccd);
-
- void updateBoxSize(int value);
-
- void setThreshold(double value);
-
- void setFrames(int value);
-
- void setCaptureComplete();
-
-signals:
- void newLog();
- //void autoFocusFinished(bool status, double finalHFR);
- void suspendGuiding(bool suspend);
- void filterLockUpdated(ISD::GDInterface *filter, int lockedIndex);
- void newStatus(Ekos::FocusState state);
- void newStarPixmap(QPixmap &);
- void newProfilePixmap(QPixmap &);
- void newHFR(double hfr);
-
-private:
- void drawHFRPlot();
- void drawProfilePlot();
- void getAbsFocusPosition();
- void autoFocusAbs();
- void autoFocusRel();
- void resetButtons();
-
- // Devices needed for Focus operation
- ISD::Focuser *currentFocuser;
- ISD::CCD *currentCCD;
-
- // Optional device filter
- ISD::GDInterface *currentFilter;
- // Current filter position
- int currentFilterIndex;
- // True if we need to change filter position and wait for result before continuing capture
- bool filterPositionPending;
-
- // List of Focusers
- QList<ISD::Focuser*> Focusers;
- // List of CCDs
- QList<ISD::CCD *> CCDs;
- // They're generic GDInterface because they could be either ISD::CCD or ISD::Filter
- QList<ISD::GDInterface *> Filters;
-
- // As the name implies
- FocusDirection lastFocusDirection;
- // What type of focusing are we doing right now?
- FocusType focusType;
-
- /*********************
- * HFR Club variables
- *********************/
-
- // Current HFR value just fetched from FITS file
- double currentHFR;
- // Last HFR value recorded
- double lastHFR;
- // If (currentHFR > deltaHFR) we start the autofocus process.
- double minimumRequiredHFR;
- // Maximum HFR recorded
- double maxHFR;
- // Is HFR increasing? We're going away from the sweet spot! If HFRInc=1, we re-capture just to make sure HFR calculations are correct, if HFRInc > 1, we switch directions
- int HFRInc;
- // If HFR decreasing? Well, good job. Once HFR start decreasing, we can start calculating HFR slope and estimating our next move.
- int HFRDec;
- // How many frames have we captured thus far? Do we need to average them?
- uint8_t frameNum;
-
- /****************************
- * Absolute position focusers
- ****************************/
- // Absolute focus position
- double currentPosition;
- // What was our position before we started the focus process?
- int initialFocuserAbsPosition;
- // Pulse duration in ms for relative focusers that only support timers, or the number of ticks in a relative or absolute focuser
- int pulseDuration;
- // Does the focuser support absolute motion?
- bool canAbsMove;
- // Does the focuser support relative motion?
- bool canRelMove;
- // Range of motion for our lovely absolute focuser
- double absMotionMax, absMotionMin;
- // How many iterations have we completed now in our absolute autofocus algorithm? We can't go forever
- int absIterations;
-
- /****************************
- * Misc. variables
- ****************************/
-
- // Are we in the process of capturing an image?
- bool captureInProgress;
- // Was the frame modified by us? Better keep track since we need to return it to its previous state once we are done with the focus operation.
- //bool frameModified;
- // Was the modified frame subFramed?
- bool subFramed;
- // If the autofocus process fails, let's not ruin the capture session probably taking place in the next tab. Instead, we should restart it and try again, but we keep count until we hit MAXIMUM_RESET_ITERATIONS
- // and then we truly give up.
- int resetFocusIteration;
- // Which filter must we use once the autofocus process kicks in?
- int lockedFilterIndex;
- // Keep track of what we're doing right now
- bool inAutoFocus, inFocusLoop, inSequenceFocus, m_autoFocusSuccesful, resetFocus;
- // Did we reverse direction?
- bool reverseDir;
- // Did the user or the auto selection process finish selecting our focus star?
- //bool starSelected;
- // Target frame dimensions
- //int fx,fy,fw,fh;
- // Origianl frame dimensions
- //int orig_x, orig_y, orig_w, orig_h;
- // If HFR=-1 which means no stars detected, we need to decide how many times should the re-capture process take place before we give up or reverse direction.
- int noStarCount;
- // Track which upload mode the CCD is set to. If set to UPLOAD_LOCAL, then we need to switch it to UPLOAD_CLIENT in order to do focusing, and then switch it back to UPLOAD_LOCAL
- ISD::CCD::UploadMode rememberUploadMode;
- // Previous binning setting
- int activeBin;
- // HFR values for captured frames before averages
- double HFRFrames[5];
-
- QStringList logText;
- ITextVectorProperty *filterName;
- INumberVectorProperty *filterSlot;
-
- /****************************
- * Plot variables
- ****************************/
-
- // Plot minimum and maximum positions
- int minPos, maxPos;
- // List of V curve plot points
- // Custom Plot object
- QCustomPlot *customPlot;
- // V-Curve graph
- QCPGraph *v_graph;
-
- // Last gaussian fit values
- QVector<double> firstGausIndexes, lastGausIndexes;
- QVector<double> firstGausFrequencies, lastGausFrequencies;
- QCPGraph *currentGaus, *firstGaus, *lastGaus;
-
- QVector<double> hfr_position, hfr_value;
-
- // Pixmaps
- QPixmap starPixmap;
- QPixmap profilePixmap;
-
- // State
- Ekos::FocusState state;
-
- // FITS Scale
- FITSScale defaultScale;
-
- // CCD Chip frame settings
- QMap<ISD::CCDChip *, QVariantMap> frameSettings;
-
- // Selected star coordinates
- QVector3D starCenter;
-};
-
-}
-
-#endif // Focus_H
diff --git a/kstars/ekos/focus.ui b/kstars/ekos/focus.ui
deleted file mode 100644
index 91f8bf4..0000000
--- a/kstars/ekos/focus.ui
+++ /dev/null
@@ -1,938 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>Focus</class>
- <widget class="QWidget" name="Focus">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>615</width>
- <height>385</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_8">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_13">
- <item>
- <layout class="QVBoxLayout" name="verticalLayout_7">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_12">
- <item>
- <widget class="QGroupBox" name="ccdGroup">
- <property name="title">
- <string>CCD &amp;&amp; Filter Wheel</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_4">
- <property name="leftMargin">
- <number>5</number>
- </property>
- <property name="topMargin">
- <number>5</number>
- </property>
- <property name="rightMargin">
- <number>5</number>
- </property>
- <property name="bottomMargin">
- <number>5</number>
- </property>
- <property name="spacing">
- <number>3</number>
- </property>
- <item row="2" column="1">
- <widget class="QComboBox" name="FilterCaptureCombo">
- <property name="enabled">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QLabel" name="FilterPosLabel">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="toolTip">
- <string>Number of images to capture</string>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>Filter #:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="3">
- <layout class="QHBoxLayout" name="horizontalLayout_10">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <widget class="QComboBox" name="FilterPosCombo">
- <property name="enabled">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="lockFilterCheck">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="toolTip">
- <string>If locked, the focus process will always use the specified filter when performing autofocus.
-Otherwise, the autofocus process will utilize whatever filter currently set by the driver.</string>
- </property>
- <property name="text">
- <string>Lock</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="label_8">
- <property name="toolTip">
- <string>Apply filter to image after capture to enhance it</string>
- </property>
- <property name="text">
- <string>Effect:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QComboBox" name="filterCombo">
- <item>
- <property name="text">
- <string>--</string>
- </property>
- </item>
- </widget>
- </item>
- <item row="1" column="3">
- <widget class="QComboBox" name="ISOCombo">
- <property name="enabled">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="FilterCaptureLabel">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="toolTip">
- <string>Filter Wheel</string>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>FW:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QComboBox" name="CCDCaptureCombo"/>
- </item>
- <item row="0" column="2">
- <widget class="QLabel" name="label_7">
- <property name="text">
- <string>Exposure:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="3">
- <layout class="QHBoxLayout" name="horizontalLayout_3">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <widget class="QDoubleSpinBox" name="exposureIN">
- <property name="decimals">
- <number>3</number>
- </property>
- <property name="minimum">
- <double>0.001000000000000</double>
- </property>
- <property name="maximum">
- <double>300.000000000000000</double>
- </property>
- <property name="singleStep">
- <double>0.100000000000000</double>
- </property>
- <property name="value">
- <double>0.500000000000000</double>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_13">
- <property name="text">
- <string>secs</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_18">
- <property name="text">
- <string>Bin:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QComboBox" name="binningCombo">
- <property name="enabled">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QLabel" name="ISOLabel">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>ISO:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="3">
- <widget class="QPushButton" name="resetFrameB">
- <property name="toolTip">
- <string>Reset focus subframe to full capture</string>
- </property>
- <property name="text">
- <string>Reset</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="textLabel1_6">
- <property name="toolTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>CCD:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="2">
- <widget class="QLabel" name="label_17">
- <property name="text">
- <string>Frame:</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="controlGroup">
- <property name="title">
- <string>Focuser</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <property name="spacing">
- <number>3</number>
- </property>
- <property name="leftMargin">
- <number>3</number>
- </property>
- <property name="topMargin">
- <number>3</number>
- </property>
- <property name="rightMargin">
- <number>3</number>
- </property>
- <property name="bottomMargin">
- <number>3</number>
- </property>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_5">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <layout class="QGridLayout" name="gridLayout_3">
- <property name="spacing">
- <number>1</number>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="label_14">
- <property name="text">
- <string>Focuser:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QComboBox" name="focuserCombo"/>
- </item>
- <item row="0" column="2">
- <widget class="QPushButton" name="focusInB">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Focus In</string>
- </property>
- </widget>
- </item>
- <item row="0" column="3">
- <widget class="QPushButton" name="focusOutB">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Focus Out</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_16">
- <property name="text">
- <string>Ticks:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QSpinBox" name="absTicksSpin">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QPushButton" name="setAbsTicksB">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Set</string>
- </property>
- </widget>
- </item>
- <item row="1" column="3">
- <widget class="QPushButton" name="captureB">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Capture</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="horizontalSpacer_4">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <widget class="QLabel" name="label_15">
- <property name="text">
- <string>Mode:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="manualModeR">
- <property name="text">
- <string>&amp;Manual</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="AutoModeR">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>A&amp;uto</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_6">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <widget class="QPushButton" name="startFocusB">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Start Focus</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="stopFocusB">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Stop</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="startLoopB">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Start Framing</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer_3">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- </layout>
- <zorder>focusInB</zorder>
- <zorder>focusOutB</zorder>
- <zorder>label_15</zorder>
- <zorder>focusInB</zorder>
- <zorder>focusOutB</zorder>
- <zorder>captureB</zorder>
- <zorder>horizontalSpacer_3</zorder>
- <zorder>horizontalSpacer_4</zorder>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout" stretch="2,1,0">
- <item>
- <widget class="QGroupBox" name="groupBox_4">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>200</height>
- </size>
- </property>
- <property name="title">
- <string>V-Curve</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <property name="spacing">
- <number>1</number>
- </property>
- <property name="leftMargin">
- <number>3</number>
- </property>
- <property name="topMargin">
- <number>3</number>
- </property>
- <property name="rightMargin">
- <number>3</number>
- </property>
- <property name="bottomMargin">
- <number>3</number>
- </property>
- <item>
- <widget class="QCustomPlot" name="HFRPlot" native="true">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>200</width>
- <height>100</height>
- </size>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_4">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>HFR:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="HFROut">
- <property name="readOnly">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_6">
- <property name="text">
- <string>pixels</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Expanding</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>13</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="clearDataB">
- <property name="text">
- <string>Clear Data</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="profileGroup">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title">
- <string>Relative Profile</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_6">
- <property name="spacing">
- <number>1</number>
- </property>
- <property name="leftMargin">
- <number>3</number>
- </property>
- <property name="topMargin">
- <number>3</number>
- </property>
- <property name="rightMargin">
- <number>3</number>
- </property>
- <property name="bottomMargin">
- <number>3</number>
- </property>
- <item>
- <widget class="QCustomPlot" name="profilePlot" native="true">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>100</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>16777215</width>
- <height>16777215</height>
- </size>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_2">
- <property name="title">
- <string>Autofocus Options</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_3">
- <property name="spacing">
- <number>1</number>
- </property>
- <property name="leftMargin">
- <number>3</number>
- </property>
- <property name="topMargin">
- <number>3</number>
- </property>
- <property name="rightMargin">
- <number>3</number>
- </property>
- <property name="bottomMargin">
- <number>3</number>
- </property>
- <item>
- <layout class="QGridLayout" name="gridLayout_2">
- <property name="spacing">
- <number>3</number>
- </property>
- <item row="0" column="0">
- <widget class="QCheckBox" name="kcfg_autoSelectStar">
- <property name="toolTip">
- <string>Automatically select the best focus star from the image</string>
- </property>
- <property name="text">
- <string>Auto Select Star</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QCheckBox" name="kcfg_subFrame">
- <property name="toolTip">
- <string>Subframe around the focus star during the autofocus procedure</string>
- </property>
- <property name="text">
- <string>Sub Frame</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QCheckBox" name="darkFrameCheck">
- <property name="toolTip">
- <string/>
- </property>
- <property name="text">
- <string>Dark Frame</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QCheckBox" name="suspendGuideCheck">
- <property name="toolTip">
- <string>Suspend Guiding while autofocus in progress</string>
- </property>
- <property name="text">
- <string>Suspend Guiding</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="Line" name="line">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="label_10">
- <property name="whatsThis">
- <string>Delay between two consequent focus images</string>
- </property>
- <property name="text">
- <string>Box Size:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QSpinBox" name="focusBoxSize">
- <property name="minimum">
- <number>16</number>
- </property>
- <property name="maximum">
- <number>256</number>
- </property>
- <property name="singleStep">
- <number>16</number>
- </property>
- <property name="value">
- <number>64</number>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QLabel" name="label_11">
- <property name="text">
- <string>pixels</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_12">
- <property name="toolTip">
- <string>Maximum travel in ticks before the autofocus process aborts</string>
- </property>
- <property name="text">
- <string>Max Travel:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QDoubleSpinBox" name="maxTravelIN">
- <property name="minimum">
- <double>10.000000000000000</double>
- </property>
- <property name="maximum">
- <double>50000.000000000000000</double>
- </property>
- <property name="singleStep">
- <double>100.000000000000000</double>
- </property>
- <property name="value">
- <double>10000.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QLabel" name="label_9">
- <property name="text">
- <string>ticks</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label">
- <property name="toolTip">
- <string>&lt;b&gt;Initial&lt;/b&gt; step size in ticks to cause a noticeable change in HFR value. For timer based focuser, it is the initial time in milliseconds to move the focuser inward or outward</string>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>Step:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QSpinBox" name="stepIN">
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>10000</number>
- </property>
- <property name="singleStep">
- <number>10</number>
- </property>
- <property name="value">
- <number>250</number>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>ticks</string>
- </property>
- </widget>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="label_4">
- <property name="toolTip">
- <string>Decrease value to narrow optimal focus point solution radius. Increase to expand solution radius</string>
- </property>
- <property name="text">
- <string>Tolerance:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QDoubleSpinBox" name="toleranceIN">
- <property name="minimum">
- <double>0.010000000000000</double>
- </property>
- <property name="maximum">
- <double>20.000000000000000</double>
- </property>
- <property name="singleStep">
- <double>0.100000000000000</double>
- </property>
- <property name="value">
- <double>1.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="3" column="2">
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>%</string>
- </property>
- </widget>
- </item>
- <item row="4" column="0">
- <widget class="QLabel" name="label_19">
- <property name="toolTip">
- <string>Increase to restrict the centroid to bright cores. Decrease to enclose fuzzy stars.</string>
- </property>
- <property name="text">
- <string>Threshold:</string>
- </property>
- </widget>
- </item>
- <item row="4" column="1">
- <widget class="QDoubleSpinBox" name="thresholdSpin">
- <property name="minimum">
- <double>90.000000000000000</double>
- </property>
- <property name="maximum">
- <double>500.000000000000000</double>
- </property>
- <property name="singleStep">
- <double>10.000000000000000</double>
- </property>
- <property name="value">
- <double>150.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="4" column="2">
- <widget class="QLabel" name="label_20">
- <property name="text">
- <string>%</string>
- </property>
- </widget>
- </item>
- <item row="5" column="0">
- <widget class="QLabel" name="label_21">
- <property name="toolTip">
- <string>Number of frames to average</string>
- </property>
- <property name="text">
- <string>Frames:</string>
- </property>
- </widget>
- </item>
- <item row="5" column="1">
- <widget class="QSpinBox" name="focusFramesSpin">
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>5</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="horizontalSpacer_5">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>1</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- <zorder>groupBox_2</zorder>
- <zorder>horizontalSpacer_5</zorder>
- </widget>
- <customwidgets>
- <customwidget>
- <class>QCustomPlot</class>
- <extends>QWidget</extends>
- <header>auxiliary/qcustomplot.h</header>
- <container>1</container>
- </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
diff --git a/kstars/ekos/guide.h b/kstars/ekos/guide.h
deleted file mode 100644
index 73a8f8a..0000000
--- a/kstars/ekos/guide.h
+++ /dev/null
@@ -1,348 +0,0 @@
-/* Ekos guide tool
- Copyright (C) 2012 Jasem Mutlaq <mutlaqja@ikarustech.com>
-
- This application is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
- */
-
-#ifndef guide_H
-#define guide_H
-
-#include <QTimer>
-#include <QtDBus/QtDBus>
-
-#include "ekos.h"
-#include "guide/common.h"
-#include "guide.h"
-#include "fitsviewer/fitscommon.h"
-#include "indi/indistd.h"
-#include "indi/inditelescope.h"
-#include "indi/indiccd.h"
-#include "ui_guide.h"
-
-class QTabWidget;
-class cgmath;
-class internalCalibration;
-class internalGuider;
-class FITSData;
-
-namespace Ekos
-{
-
-class PHD2;
-
-/**
- *@class Guide
- *@short Performs calibration and autoguiding using an ST4 port or directly via the INDI driver. Can be used with the following external guiding applications:
- * PHD2
- *@author Jasem Mutlaq
- *@version 1.2
- */
-class Guide : public QWidget, public Ui::Guide
-{
-
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.Ekos.Guide")
-
-public:
- Guide();
- ~Guide();
-
- enum GuiderStage { CALIBRATION_STAGE, GUIDE_STAGE };
- enum GuiderProcess { GUIDE_INTERNAL, GUIDE_PHD2 };
-
- /** @defgroup GuideDBusInterface Ekos DBus Interface - Capture Module
- * Ekos::Guide interface provides advanced scripting capabilities to calibrate and guide a mount via a CCD camera.
- */
-
- /*@{*/
-
- /** DBUS interface function.
- * select the CCD device from the available CCD drivers.
- * @param device The CCD device name
- * @return Returns true if CCD device is found and set, false otherwise.
- */
- Q_SCRIPTABLE bool setCCD(QString device);
-
- /** DBUS interface function.
- * select the ST4 device from the available ST4 drivers.
- * @param device The ST4 device name
- * @return Returns true if ST4 device is found and set, false otherwise.
- */
- Q_SCRIPTABLE bool setST4(QString device);
-
- /** DBUS interface function.
- * @return Returns List of registered ST4 devices.
- */
- Q_SCRIPTABLE QStringList getST4Devices();
-
- /** DBUS interface function.
- * @return Returns true if calibraiton is in progress.
- */
- Q_SCRIPTABLE bool isCalibrating();
-
- /** DBUS interface function.
- * @return Returns true if calibration procedure is complete.
- */
- Q_SCRIPTABLE bool isCalibrationComplete();
-
- /** DBUS interface function.
- * @return Returns true if calibration procedure is successful.
- */
- Q_SCRIPTABLE bool isCalibrationSuccessful();
-
- /** DBUS interface function.
- * @return Returns true if autoguiding is in progress.
- */
- Q_SCRIPTABLE bool isGuiding();
-
- /** DBUS interface function.
- * @return Returns guiding deviation from guide star in arcsecs. First elemenet is RA guiding deviation, second element is DEC guiding deviation.
- */
- Q_SCRIPTABLE QList<double> getGuidingDeviation();
-
- /** DBUS interface function.
- * Set CCD exposure value
- * @value exposure value in seconds.
- */
- Q_SCRIPTABLE Q_NOREPLY void setExposure(double value);
-
- /** DBUS interface function.
- * Set image filter to apply to the image after capture.
- * @param value Image filter (Auto Stretch, High Contrast, Equalize, High Pass)
- */
- Q_SCRIPTABLE Q_NOREPLY void setImageFilter(const QString & value);
-
- /** DBUS interface function.
- * Set calibration Use Two Axis option. The options must be set before starting the calibration operation. If no options are set, the options loaded from the user configuration are used.
- * @param enable if true, calibration will be performed in both RA and DEC axis. Otherwise, only RA axis will be calibrated.
- */
- Q_SCRIPTABLE Q_NOREPLY void setCalibrationTwoAxis(bool enable);
-
- /** DBUS interface function.
- * Set auto star calibration option. The options must be set before starting the calibration operation. If no options are set, the options loaded from the user configuration are used.
- * @param enable if true, Ekos will attempt to automatically select the best guide star and proceed with the calibration procedure.
- */
- Q_SCRIPTABLE Q_NOREPLY void setCalibrationAutoStar(bool enable);
-
- /** DBUS interface function.
- * In case of automatic star selection, calculate the appropriate square size given the selected star width. The options must be set before starting the calibration operation. If no options are set, the options loaded from the user configuration are used.
- * @param enable if true, Ekos will attempt to automatically select the best square size for calibration and guiding phases.
- */
- Q_SCRIPTABLE Q_NOREPLY void setCalibrationAutoSquareSize(bool enable);
-
- /** DBUS interface function.
- * Set calibration dark frame option. The options must be set before starting the calibration operation. If no options are set, the options loaded from the user configuration are used.
- * @param enable if true, a dark frame will be captured to subtract from the light frame.
- */
- Q_SCRIPTABLE Q_NOREPLY void setDarkFrameEnabled(bool enable);
-
- /** DBUS interface function.
- * Set calibration parameters.
- * @param pulseDuration Pulse duration in milliseconds to use in the calibration steps.
- */
- Q_SCRIPTABLE Q_NOREPLY void setCalibrationPulseDuration(int pulseDuration);
-
- /** DBUS interface function.
- * Set guiding box size. The options must be set before starting the guiding operation. If no options are set, the options loaded from the user configuration are used.
- * @param boxSizeIndex box size index (0 to 4) for box size from 8 to 128 pixels. The box size should be suitable for the size of the guide star selected. The boxSize is also used to select the subframe size around the guide star. Default is 16 pixels
- */
- Q_SCRIPTABLE Q_NOREPLY void setGuideBoxSizeIndex(int boxSizeIndex);
-
- /** DBUS interface function.
- * Set guiding algorithm. The options must be set before starting the guiding operation. If no options are set, the options loaded from the user configuration are used.
- * @param algorithm Select the algorithm used to calculate the centroid of the guide star (Smart, Fast, Auto, No thresh).
- */
- Q_SCRIPTABLE Q_NOREPLY void setGuideAlgorithm(const QString & algorithm);
-
- /** DBUS interface function.
- * Set guiding options. The options must be set before starting the guiding operation. If no options are set, the options loaded from the user configuration are used.
- * @param enable if true, it will select a subframe around the guide star depending on the boxSize size.
- */
- Q_SCRIPTABLE Q_NOREPLY void setSubFrameEnabled(bool enable);
-
- /** DBUS interface function.
- * Set rapid guiding option. The options must be set before starting the guiding operation. If no options are set, the options loaded from the user configuration are used.
- * @param enable if true, it will activate RapidGuide in the CCD driver. When Rapid Guide is used, no frames are sent to Ekos for analysis and the centeroid calculations are done in the CCD driver.
- */
- Q_SCRIPTABLE Q_NOREPLY void setGuideRapid(bool enable);
-
- /** DBUS interface function.
- * Enable or disables dithering
- * @param enable if true, dithering is enabled and is performed after each exposure is complete. Otheriese, dithering is disabled.
- * @param value dithering range in pixels. Ekos will move the guide star in a random direction for the specified dithering value in pixels.
- */
- Q_SCRIPTABLE Q_NOREPLY void setDither(bool enable, double value);
-
-
- /** DBUS interface function.
- * Selects which guiding process to utilize for calibration & guiding.
- * @param guideProcess Either use Ekos internal guider or external PHD2 process.
- */
- Q_SCRIPTABLE Q_NOREPLY void setGuiderProcess(int guiderProcess);
-
- /** @}*/
-
- void addCCD(ISD::GDInterface *newCCD);
- void setTelescope(ISD::GDInterface *newTelescope);
- void addST4(ISD::ST4 *newST4);
- void setAO(ISD::ST4 *newAO);
-
- bool isDithering();
-
- void addGuideHead(ISD::GDInterface *newCCD);
- void syncTelescopeInfo();
- void syncCCDInfo();
-
- void clearLog();
-
- void setDECSwap(bool enable);
- bool sendPulse( GuideDirection ra_dir, int ra_msecs, GuideDirection dec_dir, int dec_msecs );
- bool sendPulse( GuideDirection dir, int msecs );
-
- QString getLogText() { return logText.join("\n"); }
-
- QVector3D getStarPosition() { return starCenter; }
-
- // Tracking Box
- void setTrackingBoxSize(int index) { boxSizeCombo->setCurrentIndex(index); }
- int getTrackingBoxSize() { return boxSizeCombo->currentText().toInt(); }
-
- double getReticleAngle();
-
- void startRapidGuide();
- void stopRapidGuide();
-
- static QString getStatusString(Ekos::GuideState state);
-
-public slots:
-
- /** DBUS interface function.
- * Start the autoguiding operation.
- * @return Returns true if guiding started successfully, false otherwise.
- */
- Q_SCRIPTABLE bool startGuiding();
-
- /** DBUS interface function.
- * Stop the autoguiding operation.
- * @return Returns true if guiding stopped successfully, false otherwise.
- */
- Q_SCRIPTABLE bool stopGuiding();
-
- /** DBUS interface function.
- * Start the calibration operation.
- * @return Returns true if calibration started successfully, false otherwise.
- */
- Q_SCRIPTABLE bool startCalibration();
-
- /** DBUS interface function.
- * Stop the calibration operation.
- * @return Returns true if calibration stopped successfully, false otherwise.
- */
- Q_SCRIPTABLE bool stopCalibration();
-
- /** DBUS interface function.
- * Capture a guide frame
- * @return Returns true if capture command is sent successfully to INDI server.
- */
- Q_SCRIPTABLE bool capture();
-
- /** DBUS interface function.
- * Attempts to automatically select a star from the current guide frame
- * @return Returns true if a star is selected successfully, false otherwise
- */
- Q_SCRIPTABLE bool selectAutoStar();
-
- void checkCCD(int ccdNum=-1);
- void checkExposureValue(ISD::CCDChip *targetChip, double exposure, IPState state);
- void newFITS(IBLOB*);
- void newST4(int index);
- void processRapidStarData(ISD::CCDChip *targetChip, double dx, double dy, double fit);
- void updateGuideDriver(double delta_ra, double delta_dec);
-
- // Auto Calibration Guiding (Cablirate first then start guiding immediately)
- void startAutoCalibrateGuiding();
- void checkAutoCalibrateGuiding(Ekos::GuideState state);
-
- void dither();
- void setSuspended(bool enable);
-
- void appendLogText(const QString &);
-
- void setStatus(Ekos::GuideState newState);
-
- // Star Position
- void setStarPosition(const QVector3D &newCenter, bool updateNow);
-
- // Capture
- void setCaptureComplete();
-
-protected slots:
- void updateCCDBin(int index);
-
- /**
- * @brief processCCDNumber Process number properties arriving from CCD. Currently, binning changes are processed.
- * @param nvp pointer to number property.
- */
- void processCCDNumber(INumberVectorProperty *nvp);
-
- void saveDefaultGuideExposure();
-
- void setDefaultCCD(QString ccd);
- void setDefaultST4(QString st4);
-
- void updateTrackingBoxSize(int currentIndex);
-
-signals:
- void newLog();
- void newStatus(Ekos::GuideState status);
-
- void newStarPixmap(QPixmap &);
- void newProfilePixmap(QPixmap &);
-
- //void guideReady();
- void newAxisDelta(double delta_ra, double delta_dec);
- //void autoGuidingToggled(bool);
- //void ditherComplete();
- //void ditherFailed();
- void ditherToggled(bool);
- void guideChipUpdated(ISD::CCDChip*);
-
-private:
- void updateGuideParams();
- void syncTrackingBoxPosition();
-
- ISD::CCD *currentCCD;
- ISD::Telescope *currentTelescope;
- ISD::ST4* ST4Driver;
- ISD::ST4* AODriver;
- ISD::ST4* GuideDriver;
-
- QList<ISD::ST4*> ST4List;
- QList<ISD::CCD *> CCDs;
-
- QTabWidget *tabWidget;
-
- cgmath *pmath;
- internalCalibration *calibration;
- internalGuider *guider;
- PHD2 *phd2;
-
- bool useGuideHead;
- bool isSuspended;
-
- QVector3D starCenter;
-
- QStringList logText;
-
- double ccd_hor_pixel, ccd_ver_pixel, focal_length, aperture, guideDeviationRA, guideDeviationDEC;
- bool rapidGuideReticleSet;
-
- GuideState state;
-};
-
-}
-
-#endif // guide_H
diff --git a/kstars/ekos/guide.ui b/kstars/ekos/guide.ui
deleted file mode 100644
index aeab9a5..0000000
--- a/kstars/ekos/guide.ui
+++ /dev/null
@@ -1,182 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>Guide</class>
- <widget class="QWidget" name="Guide">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>133</width>
- <height>178</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <layout class="QHBoxLayout" name="tabLayout">
- <property name="spacing">
- <number>1</number>
- </property>
- <item>
- <layout class="QGridLayout" name="gridLayout">
- <property name="spacing">
- <number>1</number>
- </property>
- <item row="7" column="0">
- <widget class="QCheckBox" name="darkFrameCheck">
- <property name="toolTip">
- <string>Subtract dark frame. If no dark frame is available, a new dark frame shall be captured and saved for future use.</string>
- </property>
- <property name="text">
- <string>Dark</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QComboBox" name="guiderCombo"/>
- </item>
- <item row="4" column="1">
- <widget class="QComboBox" name="binningCombo"/>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_2">
- <property name="toolTip">
- <string>Select which device receives the guiding correction commands.</string>
- </property>
- <property name="text">
- <string>Via:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Guider:</string>
- </property>
- </widget>
- </item>
- <item row="4" column="0">
- <widget class="QLabel" name="label_4">
- <property name="toolTip">
- <string>Guide camera binning. It is recommended to set binning to 2x2 or higher.</string>
- </property>
- <property name="text">
- <string>Bin:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="label_3">
- <property name="toolTip">
- <string>Exposure time in seconds</string>
- </property>
- <property name="text">
- <string>Exp:</string>
- </property>
- </widget>
- </item>
- <item row="5" column="1">
- <widget class="QComboBox" name="boxSizeCombo">
- <item>
- <property name="text">
- <string>8</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>16</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>32</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>64</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>128</string>
- </property>
- </item>
- </widget>
- </item>
- <item row="6" column="0">
- <widget class="QLabel" name="label_8">
- <property name="toolTip">
- <string>Apply filter to image after capture to enhance it</string>
- </property>
- <property name="text">
- <string>Filters:</string>
- </property>
- </widget>
- </item>
- <item row="5" column="0">
- <widget class="QLabel" name="label_5">
- <property name="toolTip">
- <string>Guide star tracking box size. Box size must be set in accordance to the selected star size.</string>
- </property>
- <property name="text">
- <string>Box:</string>
- </property>
- </widget>
- </item>
- <item row="6" column="1">
- <widget class="QComboBox" name="filterCombo">
- <item>
- <property name="text">
- <string>--</string>
- </property>
- </item>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QDoubleSpinBox" name="exposureIN">
- <property name="maximum">
- <double>60.000000000000000</double>
- </property>
- <property name="value">
- <double>1.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QComboBox" name="ST4Combo"/>
- </item>
- <item row="8" column="0">
- <spacer name="verticalSpacer_2">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/kstars/ekos/guide.cpp b/kstars/ekos/guide/guideinterface.cpp
index bb6e106..f5e99ec 100644
--- a/kstars/ekos/guide.cpp
+++ b/kstars/ekos/guide/guideinterface.cpp
@@ -61,12 +61,6 @@ Guide::Guide() : QWidget()
guideDeviationRA = guideDeviationDEC = 0;
- tabWidget = new QTabWidget(this);
-
- tabLayout->addWidget(tabWidget);
- tabLayout->setContentsMargins(3,3,3,3);
- tabLayout->setSpacing(1);
-
exposureIN->setValue(Options::guideExposure());
connect(exposureIN, SIGNAL(editingFinished()), this, SLOT(saveDefaultGuideExposure()));
diff --git a/kstars/ekos/guide/guideinterface.h b/kstars/ekos/guide/guideinterface.h
new file mode 100644
index 0000000..703f926
--- /dev/null
+++ b/kstars/ekos/guide/guideinterface.h
@@ -0,0 +1,37 @@
+/* Ekos guide class interface
+ Copyright (C) 2016 Jasem Mutlaq <mutlaqja@ikarustech.com>
+
+ This application is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef GUIDEINTERFACE_H
+#define GUIDEINTERFACE_H
+
+#include <QObject>
+
+namespace Ekos
+{
+
+/**
+ *@class GuideInterface
+ *@short Interface skeleton for implementation of different guiding applications and/or routines
+ *@author Jasem Mutlaq
+ *@version 1.0
+ */
+class GuideInterface : public QObject
+{
+
+ Q_OBJECT
+
+public:
+ GuideInterface();
+ virtual ~GuideInterface() {}
+
+};
+
+}
+
+#endif // GUIDEINTERFACE_H
diff --git a/kstars/ekos/astrometryparser.cpp b/kstars/ekos/guide/internalguide/internalguider.cpp
index fff8ef7..bc1694c 100644
--- a/kstars/ekos/astrometryparser.cpp
+++ b/kstars/ekos/guide/internalguide/internalguider.cpp
@@ -1,5 +1,7 @@
-/* Astrometry.net Parser
- Copyright (C) 2012 Jasem Mutlaq <mutlaqja@ikarustech.com>
+/* Ekos Internal Guider Class
+ Copyright (C) 2016 Jasem Mutlaq <mutlaqja@ikarustech.com>.
+
+ Based on lin_guider
This application is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
@@ -7,21 +9,16 @@
version 2 of the License, or (at your option) any later version.
*/
-#include "astrometryparser.h"
-
-namespace Ekos
-{
+#include "internalguider.h"
+#include "Options.h"
-AstrometryParser::AstrometryParser()
+InternalGuider::InternalGuider()
{
-
}
-AstrometryParser::~AstrometryParser()
+InternalGuider::~InternalGuider()
{
}
-}
-
diff --git a/kstars/ekos/guide/internalguide/internalguider.h b/kstars/ekos/guide/internalguide/internalguider.h
new file mode 100644
index 0000000..95edc98
--- /dev/null
+++ b/kstars/ekos/guide/internalguide/internalguider.h
@@ -0,0 +1,26 @@
+/* Ekos Internal Guider Class
+ Copyright (C) 2016 Jasem Mutlaq <mutlaqja@ikarustech.com>.
+
+ Based on lin_guider
+
+ This application is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+*/
+
+#ifndef INTERNALGUIDER_H
+#define INTERNALGUIDER_H
+
+#include "../guideinterface.h"
+
+class InternalGuider : public GuideInterface
+{
+ Q_OBJECT
+
+public:
+ InternalGuider();
+ ~InternalGuider();
+};
+
+#endif // INTERNALGUIDER_H
diff --git a/kstars/ekos/mosaic.cpp b/kstars/ekos/mosaic.cpp
deleted file mode 100644
index ab282af..0000000
--- a/kstars/ekos/mosaic.cpp
+++ /dev/null
@@ -1,571 +0,0 @@
-/* Ekos Mosaic Tool
- Copyright (C) 2015 Jasem Mutlaq <mutlaqja@ikarustech.com>
-
- This application is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
- */
-
-#include "mosaic.h"
-
-#include "skymap.h"
-#include "projections/projector.h"
-
-#include "scheduler.h"
-#include "ekosmanager.h"
-
-
-#include "Options.h"
-
-namespace Ekos
-{
-
-MosaicTile::MosaicTile()
-{
- w=h=1;
- fovW=fovH=pa=0;
-
- brush.setStyle(Qt::NoBrush);
- pen.setColor(Qt::red);
- pen.setWidth(1);
-
- textBrush.setStyle(Qt::SolidPattern);
- textPen.setColor(Qt::blue);
- textPen.setWidth(2);
-
- setFlags(QGraphicsItem::ItemIsMovable);
-}
-
-MosaicTile::~MosaicTile()
-{
- qDeleteAll(tiles);
-}
-
-QRectF MosaicTile::boundingRect() const
-{
- return QRectF(0, 0, w*fovW, h*fovH);
-}
-
-void MosaicTile::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
-{
-
- if (w == 1 && h == 1)
- return;
-
- QFont defaultFont = painter->font();
- defaultFont.setPointSize(50);
- painter->setFont(defaultFont);
-
- //double center_x = (w*fovW)/2.0;
- //double center_y = (h*fovH)/2.0;
-
- //double center_x = parentItem()->boundingRect().center().x();
- // double center_y = parentItem()->boundingRect().center().y();
-
-
-// painter->save();
- // QTransform transform;
- //transform.translate(center_x, center_y);
- //transform.rotate(pa);
- //transform.translate(-center_x, -center_y);
-// transform.translate(0, 0);
-
-
-
- //painter->setTransform(transform);
-
-
-
- for (int row=0; row < h; row++)
- {
- for (int col=0; col < w; col++)
- {
- OneTile *tile = getTile(row, col);
- QRect oneRect(tile->pos.x(), tile->pos.y(), fovW, fovH);
-
- painter->setPen(pen);
- painter->setBrush(brush);
-
-
-
- painter->drawRect(oneRect);
- painter->setBrush(textBrush);
- painter->drawText(oneRect, Qt::AlignHCenter | Qt::AlignVCenter, QString("%1").arg(row*w+col+1));
-
- //painter->restore();
- }
- }
-
- //setRotation(pa);
-
-}
-QList<OneTile *> MosaicTile::getTiles() const
-{
- return tiles;
-}
-
-
-OneTile *MosaicTile::getTile(int row, int col)
-{
- int offset = row * w + col;
- if (offset < 0 || offset > tiles.size())
- return NULL;
-
- return tiles[offset];
-}
-
-void MosaicTile::updateTiles()
-{
- qDeleteAll(tiles);
- tiles.clear();
- double xOffset=fovW - fovW*overlap/100.0;
- double yOffset=fovH - fovH*overlap/100.0;
-
- double initX=fovW*overlap/100.0*(w-1) / 2.0;
- double initY=fovH*overlap/100.0*(h-1) / 2.0;
-
- double x= initX, y= initY;
-
- qDebug() << "FovW " << fovW << " FovH " << fovH;
- qDebug() << "initX" << "initX " << initX << " initY " << initY;
- qDebug() << "Offset X " << xOffset << " Y " << yOffset;
-
- for (int row=0; row < h; row++)
- {
- x = initX;
-
- for (int col=0; col < w; col++)
- {
- OneTile *tile = new OneTile();
- tile->pos.setX(x);
- tile->pos.setY(y);
-
- tile->center.setX(tile->pos.x() + (fovW/2.0));
- tile->center.setY(tile->pos.y() + (fovH/2.0));
-
- tiles.append(tile);
-
- x += xOffset;
-
- }
-
- y += yOffset;
- }
-
- double width = (w*fovW - ( (w-1) * fovW*overlap/100.0)) + initX*2;
- double height = (h*fovH - ( (h-1) * fovH*overlap/100.0)) + initY*2;
-
- QPointF centerPoint(width/2.0, height/2.0);
-
- for (int row=0; row < h; row++)
- {
- for (int col=0; col < w; col++)
- {
- OneTile *tile = getTile(row, col);
- tile->center_rot = rotatePoint(tile->center, centerPoint);
- }
- }
-
-}
-
-QPointF MosaicTile::rotatePoint(QPointF pointToRotate, QPointF centerPoint)
-{
- double angleInRadians = pa * dms::DegToRad;
- double cosTheta = cos(angleInRadians);
- double sinTheta = sin(angleInRadians);
-
- QPointF rotation_point;
-
- rotation_point.setX((cosTheta * (pointToRotate.x() - centerPoint.x()) - sinTheta * (pointToRotate.y() - centerPoint.y()) + centerPoint.x()));
- rotation_point.setY((sinTheta * (pointToRotate.x() - centerPoint.x()) + cosTheta * (pointToRotate.y() - centerPoint.y()) + centerPoint.y()));
-
- return rotation_point;
-}
-
-QPointF MosaicTile::getTileCenter(int row, int col)
-{
- OneTile *tile = getTile(row, col);
- if (tile == NULL)
- return QPointF();
- else
- return tile->center_rot;
-}
-
-Mosaic::Mosaic(Scheduler *scheduler)
-{
- setupUi(this);
-
- m_skyChart = 0;
- m_skyImage = 0;
-
- ekosScheduler = scheduler;
-
- focalLenSpin->setValue(Options::telescopeFocalLength());
- pixelWSizeSpin->setValue(Options::cameraPixelWidth());
- pixelHSizeSpin->setValue(Options::cameraPixelHeight());
- cameraWSpin->setValue(Options::cameraWidth());
- cameraHSpin->setValue(Options::cameraHeight());
- rotationSpin->setValue(Options::cameraRotation());
-
- jobsDir->setText(QDir::homePath());
-
- connect(updateB, SIGNAL(clicked()), this, SLOT(constructMosaic()));
- connect(resetB, SIGNAL(clicked()), this, SLOT(resetFOV()));
- connect(createJobsB, SIGNAL(clicked()), this, SLOT(createJobs()));
- connect(selectJobsDirB, SIGNAL(clicked()), this, SLOT(saveJobsDirectory()));
-
- targetItem = scene.addPixmap(targetPix);
- mosaicTile = new MosaicTile();
- scene.addItem(mosaicTile);
- mosaicView->setScene(&scene);
-
- selectJobsDirB->setIcon(QIcon::fromTheme("document-open-folder"));
-
- //mosaicView->setResizeAnchor(QGraphicsView::AnchorViewCenter);
-
-
- // scene.addItem(mosaicTile);
-
-}
-
-Mosaic::~Mosaic()
-{
-
-}
-
-void Mosaic::saveJobsDirectory()
-{
- QString dir = QFileDialog::getExistingDirectory(KStars::Instance(), i18n("FITS Save Directory"), jobsDir->text());
-
- if (!dir.isEmpty())
- jobsDir->setText(dir);
-}
-
-void Mosaic::setCenter(const SkyPoint &value)
-{
- center = value;
- center.apparentCoord((long double) J2000, KStars::Instance()->data()->ut().djd());
-}
-
-void Mosaic::setCameraSize(uint16_t width, uint16_t height)
-{
- cameraWSpin->setValue(width);
- cameraHSpin->setValue(height);
-}
-
-void Mosaic::setPixelSize(double pixelWSize, double pixelHSize)
-{
- pixelWSizeSpin->setValue(pixelWSize);
- pixelHSizeSpin->setValue(pixelHSize);
-}
-
-void Mosaic::setFocalLength(double focalLength)
-{
- focalLenSpin->setValue(focalLength);
-}
-
-void Mosaic::calculateFOV()
-{
- if (cameraWSpin->value() == 0 || cameraHSpin->value() == 0 || pixelWSizeSpin->value() == 0 || pixelHSizeSpin->value() == 0 || focalLenSpin->value() == 0)
- return;
-
- fovGroup->setEnabled(true);
-
- targetWFOVSpin->setMinimum(cameraWFOVSpin->value());
- targetHFOVSpin->setMinimum(cameraHFOVSpin->value());
-
- Options::setTelescopeFocalLength(focalLenSpin->value());
- Options::setCameraPixelWidth(pixelWSizeSpin->value());
- Options::setCameraPixelHeight(pixelHSizeSpin->value());
- Options::setCameraWidth(cameraWSpin->value());
- Options::setCameraHeight(cameraHSpin->value());
-
- // Calculate FOV in arcmins
- double fov_x = 206264.8062470963552 * cameraWSpin->value() * pixelWSizeSpin->value() / 60000.0 / focalLenSpin->value();
- double fov_y = 206264.8062470963552 * cameraHSpin->value() * pixelHSizeSpin->value() / 60000.0 / focalLenSpin->value();
-
- cameraWFOVSpin->setValue(fov_x);
- cameraHFOVSpin->setValue(fov_y);
-
- if (targetWFOVSpin->value() < fov_x)
- targetWFOVSpin->setValue(fov_x);
-
- if (targetHFOVSpin->value() < fov_y)
- targetHFOVSpin->setValue(fov_y);
-
- updateTargetFOV();
-}
-
-void Mosaic::updateTargetFOV()
-{
- KStars *ks = KStars::Instance();
- SkyMap *map = SkyMap::Instance();
-
- // Save the current state of the sky map
- //SkyPoint *oldFocus = map->focus();
- double oldZoomFactor = Options::zoomFactor();
-
-
- // Get double the target FOV
- ks->setApproxFOV( targetWFOVSpin->value()*2 / 60.0 );
- // map->setFocus( sp ); // FIXME: Why does setFocus() need a non-const SkyPoint pointer?
-
- center.EquatorialToHorizontal(KStarsData::Instance()->lst(), KStarsData::Instance()->geo()->lat());
-
- map->setFocusObject(NULL);
- map->setClickedPoint(&center);
- map->slotCenter();
- qApp->processEvents();
-
- // Repeat -- dirty workaround for some problem in KStars
-
- /* map->setClickedPoint(&center);
- map->slotCenter();
- qApp->processEvents();*/
-
- pixelPerArcmin = Options::zoomFactor() * dms::DegToRad / 60.0;
-
- double fov_w = map->width() / pixelPerArcmin;
- double fov_h = map->height() / pixelPerArcmin;
-
- double x = (fov_w - targetWFOVSpin->value()) / 2 * pixelPerArcmin;
- double y = (fov_h - targetHFOVSpin->value()) / 2 * pixelPerArcmin;
- double w = targetWFOVSpin->value() * pixelPerArcmin;
- double h = targetHFOVSpin->value() * pixelPerArcmin;
-
- // Get the sky map image
- if( m_skyChart )
- delete m_skyChart;
- QImage *fullSkyChart = new QImage( QSize( map->width(), map->height() ), QImage::Format_RGB32 );
- map->exportSkyImage( fullSkyChart, false ); // FIXME: This might make everything too small, should really use a mask and clip it down!
- qApp->processEvents();
- //m_skyChart = new QImage( fullSkyChart->copy( map->width()/2.0 - map->width()/8.0, map->height()/2.0 - map->height()/8.0, map->width()/4.0, map->height()/4.0 ) );
- m_skyChart = new QImage( fullSkyChart->copy(x,y,w,h));
- delete fullSkyChart;
-
- // See if we were supplied a sky image; if so, show it.
- /*if( ! imagePath.isEmpty() ) {
- if( m_skyImage )
- delete m_skyImage;
- m_skyImage = new QImage( imagePath );
- m_skyImageDisplay->setVisible( true );
- }
- else
- m_skyImageDisplay->setVisible( false );*/
-
-
- // Reset the sky-map
- map->setZoomFactor( oldZoomFactor );
- /*map->setClickedPoint( oldFocus );
- map->slotCenter();
- map->forceUpdate();
- qApp->processEvents();
-
- // Repeat -- dirty workaround for some problem in KStars
- map->setClickedPoint( oldFocus );
- map->slotCenter();
- qApp->processEvents();*/
-
-
-
- // Render the display
- //render();
-
- targetPix = QPixmap::fromImage(*m_skyChart);
- targetItem->setPixmap(targetPix);
-
- // qDebug() << "Pixmap w " << targetPix.width() << " h " << targetPix.height();
- // QRectF bound = (targetItem->boundingRect());
- scene.setSceneRect(targetItem->boundingRect());
- // mosaicView->fitInView(targetItem, Qt::KeepAspectRatio);
- // mosaicView->resize(targetItem->boundingRect().width(), targetItem->boundingRect().height());
-
-
-
-}
-
-void Mosaic::render()
-{
- if (m_skyChart == NULL)
- return;
-
- // targetPix = QPixmap::fromImage( *m_skyChart ).scaled( mosaicView->width(), mosaicView->height(), Qt::KeepAspectRatio );
- // targetItem->setPixmap(targetPix);
-
- //targetPix = QPixmap::fromImage( *m_skyChart ).scaled( mosaicView->width(), mosaicView->height(), Qt::KeepAspectRatio );
- //targetItem->setPixmap(targetPix);
-
- //double scale_x = (double) targetPix.width() / (double) m_skyChart->width();
- //double scale_y = (double) targetPix.height() / (double) m_skyChart->height();
-
- // mosaicTile->moveBy(center_x, center_y);
-
- //QPointF tile1Center = mosaicTile->scenePos();
- mosaicTile->setTransformOriginPoint(mosaicTile->boundingRect().center());
- mosaicTile->setRotation(mosaicTile->getPA());
-
- //QPointF tile1Center2 = mosaicTile->scenePos();
-// mosaicView->scale(scale_x, scale_y);
-
-
- mosaicView->show();
-
- //resizeEvent(NULL);
-
-
-
- /*scene.addPixmap(QPixmap::fromImage( *m_skyChart ).scaled( mosaicView->width(), mosaicView->height(), Qt::KeepAspectRatio ) );
- mosaicView->setScene(&scene);
- mosaicView->show();*/
- //mosaicDisplay->setPixmap( QPixmap::fromImage( *m_skyChart ).scaled( mosaicDisplay->width(), mosaicDisplay->height(), Qt::KeepAspectRatio ) );
-
-
-}
-
-void Mosaic::resizeEvent(QResizeEvent *)
-{
- //QRectF bounds = scene.itemsBoundingRect();
- QRectF bounds = targetItem->boundingRect();
- bounds.setWidth(bounds.width()*1.1);
- bounds.setHeight(bounds.height()*1.1);
- bounds.setWidth(bounds.width());
- bounds.setHeight(bounds.height());
- mosaicView->fitInView(bounds, Qt::KeepAspectRatio);
- mosaicView->centerOn(0, 0);
-
-}
-
-void Mosaic::showEvent(QShowEvent *)
-{
- //QRectF bounds = scene.itemsBoundingRect();
- QRectF bounds = targetItem->boundingRect();
- bounds.setWidth(bounds.width()*1.1);
- bounds.setHeight(bounds.height()*1.1);
- bounds.setWidth(bounds.width());
- bounds.setHeight(bounds.height());
- mosaicView->fitInView(bounds, Qt::KeepAspectRatio);
- mosaicView->centerOn(0, 0);
-}
-
-void Mosaic::resetFOV()
-{
- targetWFOVSpin->setValue(cameraWFOVSpin->value());
- targetHFOVSpin->setValue(cameraHFOVSpin->value());
-
- updateTargetFOV();
-}
-
-
-void Mosaic::constructMosaic()
-{
- if (focalLenSpin->value() == 0 || cameraWSpin->value() == 0 || pixelHSizeSpin->value() == 0)
- return;
-
- if (cameraWFOVSpin->value() == 0)
- {
- calculateFOV();
- showEvent(NULL);
- }
-
- if (mosaicWSpin->value() > 1 || mosaicHSpin->value() > 1)
- createJobsB->setEnabled(true);
-
- if (mosaicTile->getWidth() != mosaicWSpin->value() || mosaicTile->getHeight() != mosaicHSpin->value() || mosaicTile->getOverlap() != overlapSpin->value() || mosaicTile->getPA() != rotationSpin->value())
- {
- if (mosaicTile->getPA() != rotationSpin->value())
- Options::setCameraRotation(rotationSpin->value());
-
- // Update target FOV value
- targetWFOVSpin->setValue(cameraWFOVSpin->value() * mosaicWSpin->value());
- targetHFOVSpin->setValue(cameraHFOVSpin->value() * mosaicHSpin->value());
-
- updateTargetFOV();
-
- qDebug() << "Tile FOV in pixels is WIDTH " << cameraWFOVSpin->value()*pixelPerArcmin << " HEIGHT " << cameraHFOVSpin->value()*pixelPerArcmin;
-
- mosaicTile->setDimension(mosaicWSpin->value(), mosaicHSpin->value());
- mosaicTile->setPA(rotationSpin->value());
- mosaicTile->setFOV(cameraWFOVSpin->value()*pixelPerArcmin, cameraHFOVSpin->value()*pixelPerArcmin);
- mosaicTile->setOverlap(overlapSpin->value());
- mosaicTile->updateTiles();
-
- //render();
- mosaicTile->setTransformOriginPoint(mosaicTile->boundingRect().center());
- mosaicTile->setRotation(mosaicTile->getPA());
-
- jobCountSpin->setValue(mosaicTile->getWidth()*mosaicTile->getHeight());
- }
-}
-
-void Mosaic::createJobs()
-{
- qDebug() << "Target Item X " << targetItem->x() << " Y " << targetItem->y() << " Width " << targetItem->boundingRect().width() << " height " << targetItem->boundingRect().height();
-
- qDebug() << "Target SCENE Item X " << targetItem->mapToScene(targetItem->x(), targetItem->y()).x() << " Y " << targetItem->mapToScene(targetItem->x(), targetItem->y()).y();
-
- qDebug() << "Mosaic Item X " << mosaicTile->x() << " Y " << mosaicTile->y() << " Width " << mosaicTile->boundingRect().width() << " height " << mosaicTile->boundingRect().height();
-
- qDebug() << "Mosaic SCENE Item X " << mosaicTile->mapToScene(0,0).x() << " Y " << mosaicTile->mapToScene(0,0).y();
-
- qDebug() << "Center RA" << center.ra().toHMSString() << " DEC " << center.dec().toDMSString();
-
- KStars::Instance()->setApproxFOV( targetWFOVSpin->value()*2 / 60.0 );
-
- center.EquatorialToHorizontal(KStarsData::Instance()->lst(), KStarsData::Instance()->geo()->lat());
-
- SkyMap *map = SkyMap::Instance();
-
- map->setFocusObject(NULL);
- map->setClickedPoint(&center);
- map->slotCenter();
- qApp->processEvents();
-
- screenPoint = map->projector()->toScreen(&center);
- double northPA = map->projector()->findNorthPA(&center, screenPoint.x(), screenPoint.y());
-
- qDebug() << "North PA " << northPA;
- qDebug() << "Target Screen X " << screenPoint.x() << " Y " << screenPoint.y();
-
- for (int i=0; i < mosaicTile->getHeight(); i++)
- {
-
- for (int j=0; j < mosaicTile->getWidth(); j++)
- {
- OneTile *tile = mosaicTile->getTile(i, j);
- qDebug() << "Tile # " << i*mosaicTile->getWidth() + j << " X " << tile->center.x() << " Y " << tile->center.y() << endl;
- qDebug() << "Scene coords" << mosaicTile->mapToScene(tile->center);
- qDebug() << "Rotated coords" << tile->center_rot;
-
- QPointF tileScreenPoint(screenPoint.x()-targetItem->boundingRect().width()/2.0 + tile->center_rot.x(), screenPoint.y()-targetItem->boundingRect().height()/2.0 + tile->center_rot.y());
-
- tile->skyCenter = map->projector()->fromScreen(tileScreenPoint, KStarsData::Instance()->lst(), KStarsData::Instance()->geo()->lat());
- tile->skyCenter.deprecess(KStarsData::Instance()->updateNum());
-
- // TODO Check if J2000 are VALID. If they are use them to generate the jobs
- // Add directory to save job file along with sequence files
- // Add target name + part # as the prefix, and also the directory
- qDebug() << "Coords are J2000 RA " << tile->skyCenter.ra0().toHMSString() << " DEC " << tile->skyCenter.dec0().toDMSString();
-
- }
- }
-
- accept();
-}
-
-QPointF Mosaic::rotatePoint(QPointF pointToRotate, QPointF centerPoint)
-{
- double angleInRadians = rotationSpin->value() * dms::DegToRad;
- double cosTheta = cos(angleInRadians);
- double sinTheta = sin(angleInRadians);
-
- QPointF rotation_point;
-
- rotation_point.setX((cosTheta * (pointToRotate.x() - centerPoint.x()) - sinTheta * (pointToRotate.y() - centerPoint.y()) + centerPoint.x()));
- rotation_point.setY((sinTheta * (pointToRotate.x() - centerPoint.x()) + cosTheta * (pointToRotate.y() - centerPoint.y()) + centerPoint.y()));
-
- return rotation_point;
-}
-
-}
-
diff --git a/kstars/ekos/mosaic.h b/kstars/ekos/mosaic.h
deleted file mode 100644
index 120c478..0000000
--- a/kstars/ekos/mosaic.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/* Ekos Mosaic Tool
- Copyright (C) 2015 Jasem Mutlaq <mutlaqja@ikarustech.com>
-
- This application is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
- */
-
-#ifndef MOSAIC_H
-#define MOSAIC_H
-
-#include <QDialog>
-#include <QGraphicsItem>
-
-#include "skypoint.h"
-
-#include "ui_mosaic.h"
-
-namespace Ekos
-{
-
-class Scheduler;
-
-typedef struct
-{
- QPointF pos;
- QPointF center;
- QPointF center_rot;
- SkyPoint skyCenter;
-} OneTile;
-
-class MosaicTile : public QGraphicsItem
-{
-public:
- MosaicTile();
- ~MosaicTile();
-
- void setPA(double positionAngle) { pa = positionAngle*-1; }
- void setDimension(int width, int height) { w = width; h = height; }
- void setFOV(double fov_x, double fov_y) { fovW = fov_x; fovH = fov_y; }
- void setOverlap(double value) { overlap = value; }
-
- int getWidth() { return w;}
- int getHeight() { return h;}
- double getOverlap() { return overlap;}
- double getPA() { return pa; }
- double getFOVW() { return fovW;}
- double getFOVH() { return fovH;}
-
- void updateTiles();
- OneTile *getTile(int row, int col);
-
- QRectF boundingRect() const;
-
- QPointF getTileCenter(int row, int col);
-
- QList<OneTile *> getTiles() const;
-
-protected:
-
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *);
-
-private:
-
- double overlap;
- int w, h;
- double fovW, fovH;
- double pa;
-
-
- QBrush brush;
- QPen pen;
-
- QBrush textBrush;
- QPen textPen;
-
-
-
- QList<OneTile*> tiles;
-
-
- QPointF rotatePoint(QPointF pointToRotate, QPointF centerPoint);
-
-};
-
-class Mosaic : public QDialog, public Ui::mosaicDialog
-{
-
- Q_OBJECT
-
-public:
- Mosaic(Scheduler *scheduler);
- ~Mosaic();
-
- void setCameraSize(uint16_t width, uint16_t height);
- void setPixelSize(double pixelWSize, double pixelHSize);
- void setFocalLength(double focalLength);
- void setCenter(const SkyPoint &value);
-
- QString getJobsDir() { return jobsDir->text(); }
- QList<OneTile*> getJobs() { return mosaicTile->getTiles(); }
-
-protected:
- virtual void showEvent(QShowEvent *);
- virtual void resizeEvent(QResizeEvent *);
-
-public slots:
-
- void constructMosaic();
-
- void calculateFOV();
-
- void updateTargetFOV();
-
- void saveJobsDirectory();
-
- void resetFOV();
-
- void createJobs();
-
- void render();
-
-private:
-
- QPointF rotatePoint(QPointF pointToRotate, QPointF centerPoint);
-
- Scheduler *ekosScheduler;
- SkyPoint center;
- QImage *m_skyChart;
- QImage *m_skyImage;
-
- QPixmap targetPix;
- QGraphicsPixmapItem *targetItem;
-
- MosaicTile *mosaicTile;
-
- double pixelPerArcmin;
-
- QPointF screenPoint;
-
- QGraphicsScene scene;
-
-};
-
-}
-
-#endif // MOSAIC_H
diff --git a/kstars/ekos/mosaic.ui b/kstars/ekos/mosaic.ui
deleted file mode 100644
index 6c404eb..0000000
--- a/kstars/ekos/mosaic.ui
+++ /dev/null
@@ -1,746 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>mosaicDialog</class>
- <widget class="QDialog" name="mosaicDialog">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>728</width>
- <height>478</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>Mosaic Job Creator</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_3">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_10" stretch="1,10">
- <item>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QGroupBox" name="equipmentGroup">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title">
- <string>1. Equipment</string>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="2" column="2">
- <layout class="QHBoxLayout" name="horizontalLayout_4">
- <item>
- <widget class="QLabel" name="label_14">
- <property name="text">
- <string>H</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QDoubleSpinBox" name="pixelHSizeSpin">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="2" column="3">
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>um</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout_3">
- <item>
- <widget class="QLabel" name="label_13">
- <property name="text">
- <string>W</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QDoubleSpinBox" name="pixelWSizeSpin">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimum">
- <double>0.000000000000000</double>
- </property>
- <property name="value">
- <double>0.000000000000000</double>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="0" column="3">
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>mm</string>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <item>
- <widget class="QLabel" name="label_10">
- <property name="text">
- <string>H</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="cameraHSpin">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimum">
- <number>0</number>
- </property>
- <property name="maximum">
- <number>10000</number>
- </property>
- <property name="value">
- <number>0</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="label_4">
- <property name="toolTip">
- <string>Mount focal length in millimeters</string>
- </property>
- <property name="text">
- <string>Focal Length:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_11">
- <property name="toolTip">
- <string>Camera pixel size in microns</string>
- </property>
- <property name="text">
- <string>Pixel Size:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_8">
- <property name="toolTip">
- <string>Camera frame width and height in pixels</string>
- </property>
- <property name="text">
- <string>Camera:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QLabel" name="label_9">
- <property name="text">
- <string>W</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="cameraWSpin">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimum">
- <number>0</number>
- </property>
- <property name="maximum">
- <number>10000</number>
- </property>
- <property name="value">
- <number>0</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="1" column="3">
- <widget class="QLabel" name="label_15">
- <property name="text">
- <string>pixels</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QDoubleSpinBox" name="focalLenSpin">
- <property name="minimum">
- <double>0.000000000000000</double>
- </property>
- <property name="maximum">
- <double>10000.000000000000000</double>
- </property>
- <property name="value">
- <double>0.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="label_2">
- <property name="toolTip">
- <string>Camera's rotation angle (East of North) in degrees. To measure the angle, solve an image and use the astrometry solver solution's rotation angle</string>
- </property>
- <property name="text">
- <string>Rotation:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1" colspan="2">
- <widget class="QDoubleSpinBox" name="rotationSpin">
- <property name="minimum">
- <double>-360.000000000000000</double>
- </property>
- <property name="maximum">
- <double>360.000000000000000</double>
- </property>
- <property name="singleStep">
- <double>10.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="3" column="3">
- <widget class="QLabel" name="label_6">
- <property name="text">
- <string>E of N</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="fovGroup">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="title">
- <string>2. FOV</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0">
- <widget class="QLabel" name="cameraFOVLabel">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="toolTip">
- <string>Camera FOV in arc minutes as determined from equipment parameters above</string>
- </property>
- <property name="text">
- <string>Camera FOV:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label">
- <property name="toolTip">
- <string>Specify the number of rows and columns of the final mosaic image</string>
- </property>
- <property name="text">
- <string>Mosaic Grid:</string>
- </property>
- </widget>
- </item>
- <item row="4" column="1">
- <widget class="QDoubleSpinBox" name="overlapSpin">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="maximum">
- <double>20.000000000000000</double>
- </property>
- <property name="value">
- <double>5.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="0" column="4">
- <widget class="QLabel" name="cameraFOVUnits">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="text">
- <string>arcmin</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="targetFOVLabel">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="toolTip">
- <string>Final mosaic field of view size in arc minutes. Click update to calculate it or enter it manually.</string>
- </property>
- <property name="text">
- <string>Mosaic FOV:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="4">
- <widget class="QLabel" name="targetFOVUnits">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="text">
- <string>arcmin</string>
- </property>
- </widget>
- </item>
- <item row="0" column="3">
- <layout class="QHBoxLayout" name="horizontalLayout_6">
- <item>
- <widget class="QLabel" name="cameraHFOVLabel">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="text">
- <string>H</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QDoubleSpinBox" name="cameraHFOVSpin">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="readOnly">
- <bool>true</bool>
- </property>
- <property name="maximum">
- <double>3600.000000000000000</double>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="0" column="1" colspan="2">
- <layout class="QHBoxLayout" name="horizontalLayout_5">
- <item>
- <widget class="QLabel" name="cameraWFOVLabel">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="text">
- <string>W</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QDoubleSpinBox" name="cameraWFOVSpin">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="readOnly">
- <bool>true</bool>
- </property>
- <property name="maximum">
- <double>3600.000000000000000</double>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="1" column="1" colspan="2">
- <layout class="QHBoxLayout" name="horizontalLayout_11">
- <item>
- <widget class="QLabel" name="label_7">
- <property name="text">
- <string>W</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="mosaicWSpin">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>10</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="4" column="2">
- <widget class="QLabel" name="overlapUnits">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="text">
- <string>%</string>
- </property>
- </widget>
- </item>
- <item row="1" column="3">
- <layout class="QHBoxLayout" name="horizontalLayout_12">
- <item>
- <widget class="QLabel" name="label_12">
- <property name="text">
- <string>H</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="mosaicHSpin">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>10</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="4" column="0">
- <widget class="QLabel" name="overlapLabel">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="toolTip">
- <string>Percentage of overlap between two neighbouring images</string>
- </property>
- <property name="text">
- <string>Overlap:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="3">
- <layout class="QHBoxLayout" name="horizontalLayout_8">
- <item>
- <widget class="QLabel" name="targetFOVHLabel">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="text">
- <string>H</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QDoubleSpinBox" name="targetHFOVSpin">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="maximum">
- <double>3600.000000000000000</double>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="2" column="1" colspan="2">
- <layout class="QHBoxLayout" name="horizontalLayout_7">
- <item>
- <widget class="QLabel" name="targetFOVWLabel">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="text">
- <string>W</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QDoubleSpinBox" name="targetWFOVSpin">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="maximum">
- <double>3600.000000000000000</double>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox">
- <property name="title">
- <string>3. Output</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_14">
- <item>
- <widget class="QLabel" name="jobCountLabel">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="toolTip">
- <string>Number of scheduler jobs required to capture the mosaic image. Click update to calculate it</string>
- </property>
- <property name="text">
- <string>Job Count:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="jobCountSpin">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="readOnly">
- <bool>true</bool>
- </property>
- <property name="minimum">
- <number>1</number>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_13">
- <item>
- <widget class="QLabel" name="textLabel1_18">
- <property name="toolTip">
- <string>Directory to save sequence images</string>
- </property>
- <property name="whatsThis">
- <string/>
- </property>
- <property name="text">
- <string>Directory:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="jobsDir"/>
- </item>
- <item>
- <widget class="QPushButton" name="selectJobsDirB">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>28</width>
- <height>28</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>28</width>
- <height>28</height>
- </size>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_9">
- <item>
- <widget class="QPushButton" name="updateB">
- <property name="toolTip">
- <string>Calculate target FOV and number of jobs required to capture the mosaic</string>
- </property>
- <property name="text">
- <string>Update</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="resetB">
- <property name="toolTip">
- <string>Reset all parameters</string>
- </property>
- <property name="text">
- <string>Reset</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="createJobsB">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="toolTip">
- <string>Create scheduler jobs to capture the mosaic image</string>
- </property>
- <property name="text">
- <string>Create Jobs</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QGraphicsView" name="mosaicView">
- <property name="minimumSize">
- <size>
- <width>400</width>
- <height>300</height>
- </size>
- </property>
- <property name="verticalScrollBarPolicy">
- <enum>Qt::ScrollBarAlwaysOff</enum>
- </property>
- <property name="horizontalScrollBarPolicy">
- <enum>Qt::ScrollBarAlwaysOff</enum>
- </property>
- <property name="backgroundBrush">
- <brush brushstyle="Dense6Pattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="standardButtons">
- <set>QDialogButtonBox::Close</set>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <tabstops>
- <tabstop>focalLenSpin</tabstop>
- <tabstop>cameraWSpin</tabstop>
- <tabstop>cameraHSpin</tabstop>
- <tabstop>pixelWSizeSpin</tabstop>
- <tabstop>pixelHSizeSpin</tabstop>
- <tabstop>cameraWFOVSpin</tabstop>
- <tabstop>cameraHFOVSpin</tabstop>
- <tabstop>targetWFOVSpin</tabstop>
- <tabstop>targetHFOVSpin</tabstop>
- <tabstop>overlapSpin</tabstop>
- </tabstops>
- <resources/>
- <connections>
- <connection>
- <sender>buttonBox</sender>
- <signal>accepted()</signal>
- <receiver>mosaicDialog</receiver>
- <slot>accept()</slot>
- <hints>
- <hint type="sourcelabel">
- <x>248</x>
- <y>254</y>
- </hint>
- <hint type="destinationlabel">
- <x>157</x>
- <y>274</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>buttonBox</sender>
- <signal>rejected()</signal>
- <receiver>mosaicDialog</receiver>
- <slot>reject()</slot>
- <hints>
- <hint type="sourcelabel">
- <x>316</x>
- <y>260</y>
- </hint>
- <hint type="destinationlabel">
- <x>286</x>
- <y>274</y>
- </hint>
- </hints>
- </connection>
- </connections>
-</ui>
diff --git a/kstars/ekos/mount.cpp b/kstars/ekos/mount.cpp
deleted file mode 100644
index 4235b75..0000000
--- a/kstars/ekos/mount.cpp
+++ /dev/null
@@ -1,685 +0,0 @@
-/* Ekos Mount Module
- Copyright (C) 2015 Jasem Mutlaq <mutlaqja@ikarustech.com>
-
- This application is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
- */
-
-#include <KNotifications/KNotification>
-#include "mount.h"
-#include "Options.h"
-
-#include "indi/driverinfo.h"
-#include "indi/indicommon.h"
-#include "indi/clientmanager.h"
-#include "indi/indifilter.h"
-
-#include "mountadaptor.h"
-
-#include "ekosmanager.h"
-
-#include "kstars.h"
-#include "kstarsdata.h"
-#include "ksutils.h"
-
-#include <basedevice.h>
-
-extern const char *libindi_strings_context;
-
-#define UPDATE_DELAY 1000
-#define ABORT_DISPATCH_LIMIT 3
-
-namespace Ekos
-{
-
-Mount::Mount()
-{
- setupUi(this);
- new MountAdaptor(this);
- QDBusConnection::sessionBus().registerObject("/KStars/Ekos/Mount", this);
-
- currentTelescope = NULL;
-
- stopB->setIcon(QIcon::fromTheme("process-stop"));
- northB->setIcon(QIcon::fromTheme("go-up"));
- westB->setIcon(QIcon::fromTheme("go-previous"));
- eastB->setIcon(QIcon::fromTheme("go-next"));
- southB->setIcon(QIcon::fromTheme("go-down"));
-
- abortDispatch = -1;
-
- minAltLimit->setValue(Options::minimumAltLimit());
- maxAltLimit->setValue(Options::maximumAltLimit());
-
-
- QFile tempFile;
-
- if (KSUtils::openDataFile( tempFile, "go-nw.png" ) )
- {
- northwestB->setIcon(QIcon(tempFile.fileName()));
- tempFile.close();
- }
-
- if (KSUtils::openDataFile( tempFile, "go-ne.png" ) )
- {
- northeastB->setIcon(QIcon(tempFile.fileName()));
- tempFile.close();
- }
-
- if (KSUtils::openDataFile( tempFile, "go-sw.png" ) )
- {
- southwestB->setIcon(QIcon(tempFile.fileName()));
- tempFile.close();
- }
-
- if (KSUtils::openDataFile( tempFile, "go-se.png" ) )
- {
- southeastB->setIcon(QIcon(tempFile.fileName()));
- tempFile.close();
- }
-
- connect(northB, SIGNAL(pressed()), this, SLOT(move()));
- connect(northB, SIGNAL(released()), this, SLOT(stop()));
- connect(westB, SIGNAL(pressed()), this, SLOT(move()));
- connect(westB, SIGNAL(released()), this, SLOT(stop()));
- connect(southB, SIGNAL(pressed()), this, SLOT(move()));
- connect(southB, SIGNAL(released()), this, SLOT(stop()));
- connect(eastB, SIGNAL(pressed()), this, SLOT(move()));
- connect(eastB, SIGNAL(released()), this, SLOT(stop()));
- connect(northeastB, SIGNAL(pressed()), this, SLOT(move()));
- connect(northeastB, SIGNAL(released()), this, SLOT(stop()));
- connect(northwestB, SIGNAL(pressed()), this, SLOT(move()));
- connect(northwestB, SIGNAL(released()), this, SLOT(stop()));
- connect(southeastB, SIGNAL(pressed()), this, SLOT(move()));
- connect(southeastB, SIGNAL(released()), this, SLOT(stop()));
- connect(southwestB, SIGNAL(pressed()), this, SLOT(move()));
- connect(southwestB, SIGNAL(released()), this, SLOT(stop()));
- connect(stopB, SIGNAL(clicked()), this, SLOT(stop()));
- connect(saveB, SIGNAL(clicked()), this, SLOT(save()));
-
- connect(minAltLimit, SIGNAL(editingFinished()), this, SLOT(saveLimits()));
- connect(maxAltLimit, SIGNAL(editingFinished()), this, SLOT(saveLimits()));
-
- connect(enableLimitsCheck, SIGNAL(toggled(bool)), this, SLOT(enableAltitudeLimits(bool)));
- enableLimitsCheck->setChecked(Options::enableAltitudeLimits());
- altLimitEnabled = enableLimitsCheck->isChecked();
-
- updateTimer.setInterval(UPDATE_DELAY);
- connect(&updateTimer, SIGNAL(timeout()), this, SLOT(updateTelescopeCoords()));
-}
-
-Mount::~Mount()
-{
-}
-
-void Mount::setTelescope(ISD::GDInterface *newTelescope)
-{
- currentTelescope = static_cast<ISD::Telescope*> (newTelescope);
-
- connect(currentTelescope, SIGNAL(numberUpdated(INumberVectorProperty*)), this, SLOT(updateNumber(INumberVectorProperty*)), Qt::UniqueConnection);
- connect(currentTelescope, SIGNAL(switchUpdated(ISwitchVectorProperty*)), this, SLOT(updateSwitch(ISwitchVectorProperty*)), Qt::UniqueConnection);
- connect(currentTelescope, SIGNAL(newTarget(QString)), this, SIGNAL(newTarget(QString)), Qt::UniqueConnection);
-
- //Disable this for now since ALL INDI drivers now log their messages to verbose output
- //connect(currentTelescope, SIGNAL(messageUpdated(int)), this, SLOT(updateLog(int)), Qt::UniqueConnection);
-
- if (enableLimitsCheck->isChecked())
- currentTelescope->setAltLimits(minAltLimit->value(), maxAltLimit->value());
-
- updateTimer.start();
-
- syncTelescopeInfo();
-}
-
-void Mount::syncTelescopeInfo()
-{
- INumberVectorProperty * nvp = currentTelescope->getBaseDevice()->getNumber("TELESCOPE_INFO");
-
- if (nvp)
- {
-
- primaryScopeGroup->setTitle(currentTelescope->getDeviceName());
- guideScopeGroup->setTitle(i18n("%1 guide scope", currentTelescope->getDeviceName()));
-
- INumber *np = NULL;
-
- np = IUFindNumber(nvp, "TELESCOPE_APERTURE");
- if (np && np->value > 0)
- primaryScopeApertureIN->setValue(np->value);
-
- np = IUFindNumber(nvp, "TELESCOPE_FOCAL_LENGTH");
- if (np && np->value > 0)
- primaryScopeFocalIN->setValue(np->value);
-
- np = IUFindNumber(nvp, "GUIDER_APERTURE");
- if (np && np->value > 0)
- guideScopeApertureIN->setValue(np->value);
-
- np = IUFindNumber(nvp, "GUIDER_FOCAL_LENGTH");
- if (np && np->value > 0)
- guideScopeFocalIN->setValue(np->value);
-
- }
-
- ISwitchVectorProperty *svp = currentTelescope->getBaseDevice()->getSwitch("TELESCOPE_SLEW_RATE");
-
- if (svp)
- {
- slewSpeedCombo->clear();
- slewSpeedCombo->setEnabled(true);
-
- for (int i=0; i < svp->nsp; i++)
- slewSpeedCombo->addItem(i18nc(libindi_strings_context, svp->sp[i].label));
-
- int index = IUFindOnSwitchIndex(svp);
- slewSpeedCombo->setCurrentIndex(index);
- connect(slewSpeedCombo, SIGNAL(activated(int)), currentTelescope, SLOT(setSlewRate(int)), Qt::UniqueConnection);
- }
- else
- {
- slewSpeedCombo->setEnabled(false);
- disconnect(slewSpeedCombo, SIGNAL(activated(int)), currentTelescope, SLOT(setSlewRate(int)));
- }
-
- if (currentTelescope->canPark())
- {
- parkB->setEnabled(!currentTelescope->isParked());
- unparkB->setEnabled(currentTelescope->isParked());
- connect(parkB, SIGNAL(clicked()), currentTelescope, SLOT(Park()), Qt::UniqueConnection);
- connect(unparkB, SIGNAL(clicked()), currentTelescope, SLOT(UnPark()), Qt::UniqueConnection);
- }
- else
- {
- parkB->setEnabled(false);
- unparkB->setEnabled(false);
- disconnect(parkB, SIGNAL(clicked()), currentTelescope, SLOT(Park()));
- disconnect(unparkB, SIGNAL(clicked()), currentTelescope, SLOT(UnPark()));
- }
-
-}
-
-void Mount::updateTelescopeCoords()
-{
- double ra, dec;
-
- if (currentTelescope && currentTelescope->getEqCoords(&ra, &dec))
- {
- telescopeCoord.setRA(ra);
- telescopeCoord.setDec(dec);
- telescopeCoord.EquatorialToHorizontal(KStarsData::Instance()->lst(), KStarsData::Instance()->geo()->lat());
-
- raOUT->setText(telescopeCoord.ra().toHMSString());
- decOUT->setText(telescopeCoord.dec().toDMSString());
- azOUT->setText(telescopeCoord.az().toDMSString());
- altOUT->setText(telescopeCoord.alt().toDMSString());
-
- dms lst = KStarsData::Instance()->geo()->GSTtoLST( KStarsData::Instance()->clock()->utc().gst() );
- dms ha( lst.Degrees() - telescopeCoord.ra().Degrees() );
- QChar sgn('+');
- if ( ha.Hours() > 12.0 ) {
- ha.setH( 24.0 - ha.Hours() );
- sgn = '-';
- }
- haOUT->setText( QString("%1%2").arg(sgn).arg( ha.toHMSString() ) );
- lstOUT->setText(lst.toHMSString());
-
- double currentAlt = telescopeCoord.altRefracted().Degrees();
-
- if (minAltLimit->isEnabled()
- && ( currentAlt < minAltLimit->value() || currentAlt > maxAltLimit->value()))
- {
- if (currentAlt < minAltLimit->value())
- {
- // Only stop if current altitude is less than last altitude indicate worse situation
- if (currentAlt < lastAlt && (abortDispatch == -1 || (currentTelescope->isInMotion()/* && ++abortDispatch > ABORT_DISPATCH_LIMIT*/)))
- {
- appendLogText(i18n("Telescope altitude is below minimum altitude limit of %1. Aborting motion...", QString::number(minAltLimit->value(), 'g', 3)));
- currentTelescope->Abort();
- //KNotification::event( QLatin1String( "OperationFailed" ));
- KNotification::beep();
- abortDispatch++;
- }
- }
- else
- {
- // Only stop if current altitude is higher than last altitude indicate worse situation
- if (currentAlt > lastAlt && (abortDispatch == -1 || (currentTelescope->isInMotion()/* && ++abortDispatch > ABORT_DISPATCH_LIMIT*/)))
- {
- appendLogText(i18n("Telescope altitude is above maximum altitude limit of %1. Aborting motion...", QString::number(maxAltLimit->value(), 'g', 3)));
- currentTelescope->Abort();
- //KNotification::event( QLatin1String( "OperationFailed" ));
- KNotification::beep();
- abortDispatch++;
- }
- }
- }
- else
- abortDispatch = -1;
-
- lastAlt = currentAlt;
-
- newCoords(raOUT->text(), decOUT->text(), azOUT->text(), altOUT->text());
-
- emit newStatus(currentTelescope->getStatus());
-
- if (currentTelescope->isConnected() == false)
- updateTimer.stop();
- else if (updateTimer.isActive() == false)
- updateTimer.start();
- }
- else
- updateTimer.stop();
-}
-
-void Mount::updateNumber(INumberVectorProperty *nvp)
-{
- if (!strcmp(nvp->name, "TELESCOPE_INFO"))
- {
- if (nvp->s == IPS_ALERT)
- {
- QString newMessage;
- if (primaryScopeApertureIN->value() == 1 || primaryScopeFocalIN->value() == 1)
- newMessage = i18n("Error syncing telescope info. Please fill telescope aperture and focal length.");
- else
- newMessage = i18n("Error syncing telescope info. Check INDI control panel for more details.");
- if (newMessage != lastNotificationMessage)
- {
- appendLogText(newMessage);
- lastNotificationMessage = newMessage;
- }
- }
- else
- {
- syncTelescopeInfo();
- QString newMessage = i18n("Telescope info updated successfully.");
- if (newMessage != lastNotificationMessage)
- {
- appendLogText(newMessage);
- lastNotificationMessage = newMessage;
- }
-
- }
- }
-}
-
-void Mount::updateSwitch(ISwitchVectorProperty *svp)
-{
- if (!strcmp(svp->name, "TELESCOPE_SLEW_RATE"))
- {
- int index = IUFindOnSwitchIndex(svp);
- slewSpeedCombo->setCurrentIndex(index);
- }
- else if (!strcmp(svp->name, "TELESCOPE_PARK"))
- {
- ISwitch *sp = IUFindSwitch(svp, "PARK");
- if (sp)
- {
- parkB->setEnabled((sp->s == ISS_OFF));
- unparkB->setEnabled((sp->s == ISS_ON));
- }
- }
-}
-
-void Mount::appendLogText(const QString &text)
-{
- logText.insert(0, i18nc("log entry; %1 is the date, %2 is the text", "%1 %2", QDateTime::currentDateTime().toString("yyyy-MM-ddThh:mm:ss"), text));
-
- if (Options::verboseLogging())
- qDebug() << "Mount: " << text;
-
- emit newLog();
-}
-
-void Mount::updateLog(int messageID)
-{
- INDI::BaseDevice *dv = currentTelescope->getBaseDevice();
-
- QString message = QString::fromStdString(dv->messageQueue(messageID));
-
- logText.insert(0, i18nc("Message shown in Ekos Mount module", "%1", message));
-
- emit newLog();
-}
-
-void Mount::clearLog()
-{
- logText.clear();
- emit newLog();
-}
-
-void Mount::move()
-{
- QObject* obj = sender();
-
- if (obj == northB)
- {
- currentTelescope->MoveNS(ISD::Telescope::MOTION_NORTH, ISD::Telescope::MOTION_START);
- }
- else if (obj == westB)
- {
- currentTelescope->MoveWE(ISD::Telescope::MOTION_WEST, ISD::Telescope::MOTION_START);
- }
- else if (obj == southB)
- {
- currentTelescope->MoveNS(ISD::Telescope::MOTION_SOUTH, ISD::Telescope::MOTION_START);
- }
- else if (obj == eastB)
- {
- currentTelescope->MoveWE(ISD::Telescope::MOTION_EAST, ISD::Telescope::MOTION_START);
- }
- else if (obj == northwestB)
- {
- currentTelescope->MoveNS(ISD::Telescope::MOTION_NORTH, ISD::Telescope::MOTION_START);
- currentTelescope->MoveWE(ISD::Telescope::MOTION_WEST, ISD::Telescope::MOTION_START);
- }
- else if (obj == northeastB)
- {
- currentTelescope->MoveNS(ISD::Telescope::MOTION_NORTH, ISD::Telescope::MOTION_START);
- currentTelescope->MoveWE(ISD::Telescope::MOTION_EAST, ISD::Telescope::MOTION_START);
- }
- else if (obj == southwestB)
- {
- currentTelescope->MoveNS(ISD::Telescope::MOTION_SOUTH, ISD::Telescope::MOTION_START);
- currentTelescope->MoveWE(ISD::Telescope::MOTION_WEST, ISD::Telescope::MOTION_START);
- }
- else if (obj == southeastB)
- {
- currentTelescope->MoveNS(ISD::Telescope::MOTION_SOUTH, ISD::Telescope::MOTION_START);
- currentTelescope->MoveWE(ISD::Telescope::MOTION_EAST, ISD::Telescope::MOTION_START);
- }
-}
-
-void Mount::stop()
-{
- QObject* obj = sender();
-
- if (obj == stopB)
- currentTelescope->Abort();
- else if (obj == northB)
- {
- currentTelescope->MoveNS(ISD::Telescope::MOTION_NORTH, ISD::Telescope::MOTION_STOP);
- }
- else if (obj == westB)
- {
- currentTelescope->MoveWE(ISD::Telescope::MOTION_WEST, ISD::Telescope::MOTION_STOP);
- }
- else if (obj == southB)
- {
- currentTelescope->MoveNS(ISD::Telescope::MOTION_SOUTH, ISD::Telescope::MOTION_STOP);
- }
- else if (obj == eastB)
- {
- currentTelescope->MoveWE(ISD::Telescope::MOTION_EAST, ISD::Telescope::MOTION_STOP);
- }
- else if (obj == northwestB)
- {
- currentTelescope->MoveNS(ISD::Telescope::MOTION_NORTH, ISD::Telescope::MOTION_STOP);
- currentTelescope->MoveWE(ISD::Telescope::MOTION_WEST, ISD::Telescope::MOTION_STOP);
- }
- else if (obj == northeastB)
- {
- currentTelescope->MoveNS(ISD::Telescope::MOTION_NORTH, ISD::Telescope::MOTION_STOP);
- currentTelescope->MoveWE(ISD::Telescope::MOTION_EAST, ISD::Telescope::MOTION_STOP);
- }
- else if (obj == southwestB)
- {
- currentTelescope->MoveNS(ISD::Telescope::MOTION_SOUTH, ISD::Telescope::MOTION_STOP);
- currentTelescope->MoveWE(ISD::Telescope::MOTION_WEST, ISD::Telescope::MOTION_STOP);
- }
- else if (obj == southeastB)
- {
- currentTelescope->MoveNS(ISD::Telescope::MOTION_SOUTH, ISD::Telescope::MOTION_STOP);
- currentTelescope->MoveWE(ISD::Telescope::MOTION_EAST, ISD::Telescope::MOTION_STOP);
- }
-
-}
-
-void Mount::save()
-{
- INumberVectorProperty * nvp = currentTelescope->getBaseDevice()->getNumber("TELESCOPE_INFO");
-
- if (nvp)
- {
-
- primaryScopeGroup->setTitle(currentTelescope->getDeviceName());
- guideScopeGroup->setTitle(i18n("%1 guide scope", currentTelescope->getDeviceName()));
-
- INumber *np = NULL;
-
- np = IUFindNumber(nvp, "TELESCOPE_APERTURE");
- if (np)
- np->value = primaryScopeApertureIN->value();
- np = IUFindNumber(nvp, "TELESCOPE_FOCAL_LENGTH");
- if (np)
- np->value = primaryScopeFocalIN->value();
- np = IUFindNumber(nvp, "GUIDER_APERTURE");
- if (np)
- np->value = guideScopeApertureIN->value() == 1 ? primaryScopeApertureIN->value() : guideScopeApertureIN->value();
- np = IUFindNumber(nvp, "GUIDER_FOCAL_LENGTH");
- if (np)
- np->value = guideScopeFocalIN->value() == 1 ? primaryScopeFocalIN->value() : guideScopeFocalIN->value();
-
- ClientManager *clientManager = currentTelescope->getDriverInfo()->getClientManager();
-
- clientManager->sendNewNumber(nvp);
-
- currentTelescope->setConfig(SAVE_CONFIG);
-
- //appendLogText(i18n("Saving telescope information..."));
-
- }
- else
- appendLogText(i18n("Failed to save telescope information."));
-}
-
-void Mount::saveLimits()
-{
- Options::setMinimumAltLimit(minAltLimit->value());
- Options::setMaximumAltLimit(maxAltLimit->value());
- currentTelescope->setAltLimits(minAltLimit->value(), maxAltLimit->value());
-}
-
-void Mount::enableAltitudeLimits(bool enable)
-{
- Options::setEnableAltitudeLimits(enable);
-
- if (enable)
- {
- minAltLabel->setEnabled(true);
- maxAltLabel->setEnabled(true);
-
- minAltLimit->setEnabled(true);
- maxAltLimit->setEnabled(true);
-
- if (currentTelescope)
- currentTelescope->setAltLimits(minAltLimit->value(), maxAltLimit->value());
- }
- else
- {
- minAltLabel->setEnabled(false);
- maxAltLabel->setEnabled(false);
-
- minAltLimit->setEnabled(false);
- maxAltLimit->setEnabled(false);
-
- if (currentTelescope)
- currentTelescope->setAltLimits(-1, -1);
- }
-}
-
-void Mount::enableAltLimits()
-{
- //Only enable if it was already enabled before and the minAltLimit is currently disabled.
- if (altLimitEnabled && minAltLimit->isEnabled() == false)
- enableAltitudeLimits(true);
-}
-
-void Mount::disableAltLimits()
-{
- altLimitEnabled = enableLimitsCheck->isChecked();
-
- enableAltitudeLimits(false);
-
-}
-
-QList<double> Mount::getAltitudeLimits()
-{
- QList<double> limits;
-
- limits.append(minAltLimit->value());
- limits.append(maxAltLimit->value());
-
- return limits;
-}
-
-void Mount::setAltitudeLimits(double minAltitude, double maxAltitude, bool enabled)
-{
- minAltLimit->setValue(minAltitude);
- maxAltLimit->setValue(maxAltitude);
-
- enableLimitsCheck->setChecked(enabled);
-
-}
-
-bool Mount::isLimitsEnabled()
-{
- return enableLimitsCheck->isChecked();
-}
-
-bool Mount::slew(double RA, double DEC)
-{
- if (currentTelescope == NULL || currentTelescope->isConnected() == false)
- return false;
-
- return currentTelescope->Slew(RA, DEC);
-}
-
-bool Mount::abort()
-{
- return currentTelescope->Abort();
-}
-
-IPState Mount::getSlewStatus()
-{
- if (currentTelescope == NULL)
- return IPS_ALERT;
-
- return currentTelescope->getState("EQUATORIAL_EOD_COORD");
-}
-
-QList<double> Mount::getEquatorialCoords()
-{
- double ra,dec;
- QList<double> coords;
-
- currentTelescope->getEqCoords(&ra, &dec);
- coords.append(ra);
- coords.append(dec);
-
- return coords;
-}
-
-QList<double> Mount::getHorizontalCoords()
-{
- QList<double> coords;
-
- coords.append(telescopeCoord.az().Degrees());
- coords.append(telescopeCoord.alt().Degrees());
-
- return coords;
-}
-
-double Mount::getHourAngle()
-{
- dms lst = KStarsData::Instance()->geo()->GSTtoLST( KStarsData::Instance()->clock()->utc().gst() );
- dms ha( lst.Degrees() - telescopeCoord.ra().Degrees() );
- double HA = ha.Hours();
-
- if ( HA > 12.0 )
- return (24 - HA);
- else
- return HA;
-}
-
-QList<double> Mount::getTelescopeInfo()
-{
- QList<double> info;
-
- info.append(primaryScopeFocalIN->value());
- info.append(primaryScopeApertureIN->value());
- info.append(guideScopeFocalIN->value());
- info.append(guideScopeApertureIN->value());
-
- return info;
-}
-
-void Mount::setTelescopeInfo(double primaryFocalLength, double primaryAperture, double guideFocalLength, double guideAperture)
-{
- primaryScopeFocalIN->setValue(primaryFocalLength);
- primaryScopeApertureIN->setValue(primaryAperture);
- guideScopeFocalIN->setValue(guideFocalLength);
- guideScopeApertureIN->setValue(guideAperture);
-}
-
-bool Mount::canPark()
-{
- if (currentTelescope == NULL)
- return false;
-
- return currentTelescope->canPark();
-}
-
-bool Mount::park()
-{
- if (currentTelescope == NULL || currentTelescope->canPark() == false)
- return false;
-
- return currentTelescope->Park();
-}
-
-bool Mount::unpark()
-{
- if (currentTelescope == NULL || currentTelescope->canPark() == false)
- return false;
-
- return currentTelescope->UnPark();
-}
-
-Mount::ParkingStatus Mount::getParkingStatus()
-{
- if (currentTelescope == NULL || currentTelescope->canPark() == false)
- return PARKING_ERROR;
-
- ISwitchVectorProperty* parkSP = currentTelescope->getBaseDevice()->getSwitch("TELESCOPE_PARK");
-
- if (parkSP == NULL)
- return PARKING_ERROR;
-
- switch (parkSP->s)
- {
- case IPS_IDLE:
- return PARKING_IDLE;
-
- case IPS_OK:
- if (parkSP->sp[0].s == ISS_ON)
- return PARKING_OK;
- else
- return UNPARKING_OK;
- break;
-
- case IPS_BUSY:
- if (parkSP->sp[0].s == ISS_ON)
- return PARKING_BUSY;
- else
- return UNPARKING_BUSY;
-
- case IPS_ALERT:
- return PARKING_ERROR;
- }
-
- return PARKING_ERROR;
-}
-
-}
diff --git a/kstars/ekos/mount.h b/kstars/ekos/mount.h
deleted file mode 100644
index 2c8ab3b..0000000
--- a/kstars/ekos/mount.h
+++ /dev/null
@@ -1,233 +0,0 @@
-/* Ekos Mount Module
- Copyright (C) 2015 Jasem Mutlaq <mutlaqja@ikarustech.com>
-
- This application is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
- */
-
-#ifndef MOUNT_H
-#define MOUNT_H
-
-#include <QtDBus/QtDBus>
-#include "ui_mount.h"
-
-#include "indi/indistd.h"
-#include "indi/indifocuser.h"
-#include "indi/inditelescope.h"
-
-namespace Ekos
-{
-
-/**
- *@class Mount
- *@short Supports controlling INDI telescope devices including setting/retrieving mount properties, slewing, motion and speed controls, in addition to enforcing altitude limits and parking/unparking.
- *@author Jasem Mutlaq
- *@version 1.1
- */
-class Mount : public QWidget, public Ui::Mount
-{
-
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.Ekos.Mount")
-
-public:
- Mount();
- ~Mount();
-
- typedef enum { PARKING_IDLE, PARKING_OK, UNPARKING_OK, PARKING_BUSY, UNPARKING_BUSY, PARKING_ERROR } ParkingStatus;
-
- /**
- * @brief setTelescope Sets the mount module telescope interface
- * @param newTelescope pointer to telescope interface object
- */
- void setTelescope(ISD::GDInterface *newTelescope);
-
- // Log functions
- void appendLogText(const QString &);
- void clearLog();
- QString getLogText() { return logText.join("\n"); }
-
- /** @defgroup MountDBusInterface Ekos Mount DBus Interface
- * Mount interface provides advanced scripting capabilities to control INDI mounts.
- */
-
- /*@{*/
-
- /** DBUS interface function.
- * Returns the mount altitude limits.
- * @return Returns array of doubles. First item is minimum altititde in degrees. Second item is maximum altitude limit in degrees.
- */
- Q_SCRIPTABLE QList<double> getAltitudeLimits();
-
- /** DBUS interface function.
- * Sets the mount altitude limits, and whether they are enabled or disabled.
- */
- Q_SCRIPTABLE Q_NOREPLY void setAltitudeLimits(double minAltitude, double maxAltitude, bool enabled);
-
- /** DBUS interface function.
- * Returns whether the mount limits are enabled or disabled.
- * @return True if enabled, false otherwise.
- */
- Q_SCRIPTABLE bool isLimitsEnabled();
-
- /** DBUS interface function.
- * Slew the mount to the RA/DEC (JNow).
- * @param RA Right ascention is hours.
- * @param DEC Declination in degrees.
- * @return true if the command is sent successfully, false otherwise.
- */
- Q_SCRIPTABLE bool slew(double RA, double DEC);
-
- /** DBUS interface function.
- * Get equatorial coords (JNow). An array of doubles is returned. First element is RA in hours. Second elements is DEC in degrees.
- */
- Q_SCRIPTABLE QList<double> getEquatorialCoords();
-
- /** DBUS interface function.
- * Get Horizontal coords. An array of doubles is returned. First element is Azimuth in degrees. Second elements is Altitude in degrees.
- */
- Q_SCRIPTABLE QList<double> getHorizontalCoords();
-
- /** DBUS interface function.
- * Get mount hour angle in hours (-12 to +12).
- */
- Q_SCRIPTABLE double getHourAngle();
-
- /** DBUS interface function.
- * Aborts the mount motion
- * @return true if the command is sent successfully, false otherwise.
- */
- Q_SCRIPTABLE bool abort();
-
- /** DBUS interface function.
- * Get the mount slew status ("Idle","Complete", "Busy", "Error")
- */
- Q_SCRIPTABLE IPState getSlewStatus();
-
- /** DBUS interface function.
- * Get telescope and guide scope info. An array of doubles is returned in order.
- * Primary Telescope Focal Length (mm), Primary Telescope Aperture (mm), Guide Telescope Focal Length (mm), Guide Telescope Aperture (mm)
- */
- Q_SCRIPTABLE QList<double> getTelescopeInfo();
-
- /** DBUS interface function.
- * Set telescope and guide scope info. All measurements is in millimeters.
- * @param primaryFocalLength Primary Telescope Focal Length
- * @param primaryAperture Primary Telescope Aperture
- * @param guideFocalLength Guide Telescope Focal Length
- * @param guideAperture Guide Telescope Aperture
- */
- Q_SCRIPTABLE Q_NOREPLY void setTelescopeInfo(double primaryFocalLength, double primaryAperture, double guideFocalLength, double guideAperture);
-
- /** DBUS interface function.
- * Can mount park?
- */
- Q_SCRIPTABLE bool canPark();
-
- /** DBUS interface function.
- * Park mount
- */
- Q_SCRIPTABLE bool park();
-
- /** DBUS interface function.
- * Unpark mount
- */
- Q_SCRIPTABLE bool unpark();
-
- /** DBUS interface function.
- * Return parking status of the mount.
- */
- Q_SCRIPTABLE ParkingStatus getParkingStatus();
-
- /** @}*/
-
-public slots:
-
- /**
- * @brief syncTelescopeInfo Update telescope information to reflect any property changes
- */
- void syncTelescopeInfo();
- /**
- * @brief updateNumber Update number properties under watch in the mount module
- * @param nvp pointer to number property
- */
- void updateNumber(INumberVectorProperty *nvp);
-
- /**
- * @brief updateSwitch Update switch properties under watch in the mount module
- * @param svp pointer to switch property
- */
- void updateSwitch(ISwitchVectorProperty *svp);
-
- /**
- * @brief updateLog Update mount module log to include any messages arriving for the telescope driver
- * @param messageID ID of the new message
- */
- void updateLog(int messageID);
-
- /**
- * @brief updateTelescopeCoords runs every UPDATE_DELAY milliseconds to update the displayed coordinates of the mount and to ensure mount is
- * within altitude limits if the altitude limits are enabled.
- */
- void updateTelescopeCoords();
-
- /**
- * @brief move Issues command to the mount to move in a particular direction based on the pressed direcitonal buttons in the GUI
- */
- void move();
-
- /**
- * @brief stop Aborts telescope motion
- */
- void stop();
-
- /**
- * @brief save Save telescope focal length and aperture in the INDI telescope driver configuration.
- */
- void save();
-
- /**
- * @brief saveLimits Saves altitude limit to the user options and updates the INDI telescope driver limits
- */
- void saveLimits();
-
- /**
- * @brief enableAltitudeLimits Enable or disable altitude limits
- * @param enable True to enable, false to disable.
- */
- void enableAltitudeLimits(bool enable);
-
- /**
- * @brief enableAltLimits calls enableAltitudeLimits(true). This function is mostly used to enable altitude limit after a meridian flip is complete.
- */
- void enableAltLimits();
-
- /**
- * @brief disableAltLimits calls enableAltitudeLimits(false). This function is mostly used to disable altitude limit once a meridial flip process is started.
- */
- void disableAltLimits();
-
-signals:
- void newLog();
- void newCoords(const QString &ra, const QString &dec, const QString &az, const QString &alt);
- void newTarget(const QString &name);
- void newStatus(ISD::Telescope::TelescopeStatus status);
-
-private:
-
- ISD::Telescope *currentTelescope;
- QStringList logText;
- SkyPoint telescopeCoord;
- QString lastNotificationMessage;
- QTimer updateTimer;
- double lastAlt;
- int abortDispatch;
- bool altLimitEnabled;
-
-};
-
-}
-
-#endif // Mount
diff --git a/kstars/ekos/mount.ui b/kstars/ekos/mount.ui
deleted file mode 100644
index 2cf7d40..0000000
--- a/kstars/ekos/mount.ui
+++ /dev/null
@@ -1,556 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>Mount</class>
- <widget class="QWidget" name="Mount">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>505</width>
- <height>350</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_4">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <item>
- <layout class="QVBoxLayout" name="LeftLayout">
- <item>
- <widget class="QGroupBox" name="primaryScopeGroup">
- <property name="title">
- <string>Primary Telescope</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <layout class="QFormLayout" name="formLayout_2">
- <property name="fieldGrowthPolicy">
- <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>Aperture (mm):</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QDoubleSpinBox" name="primaryScopeApertureIN">
- <property name="minimum">
- <double>1.000000000000000</double>
- </property>
- <property name="maximum">
- <double>100000.000000000000000</double>
- </property>
- <property name="singleStep">
- <double>10.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_4">
- <property name="text">
- <string>Focal Length (mm)</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QDoubleSpinBox" name="primaryScopeFocalIN">
- <property name="minimum">
- <double>1.000000000000000</double>
- </property>
- <property name="maximum">
- <double>100000.000000000000000</double>
- </property>
- <property name="singleStep">
- <double>10.000000000000000</double>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0">
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>RA:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLineEdit" name="raOUT">
- <property name="readOnly">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QLabel" name="label_7">
- <property name="text">
- <string>DEC:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="3">
- <widget class="QLineEdit" name="decOUT">
- <property name="text">
- <string/>
- </property>
- <property name="readOnly">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_6">
- <property name="text">
- <string>Az:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLineEdit" name="azOUT">
- <property name="readOnly">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QLabel" name="label_8">
- <property name="text">
- <string>Alt:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="3">
- <widget class="QLineEdit" name="altOUT">
- <property name="readOnly">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_9">
- <property name="text">
- <string>HA:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLineEdit" name="haOUT">
- <property name="readOnly">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QLabel" name="label_10">
- <property name="text">
- <string>LST</string>
- </property>
- </widget>
- </item>
- <item row="2" column="3">
- <widget class="QLineEdit" name="lstOUT">
- <property name="readOnly">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="guideScopeGroup">
- <property name="title">
- <string>Guide Telescope</string>
- </property>
- <layout class="QFormLayout" name="formLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Aperture (mm):</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QDoubleSpinBox" name="guideScopeApertureIN">
- <property name="minimum">
- <double>1.000000000000000</double>
- </property>
- <property name="maximum">
- <double>100000.000000000000000</double>
- </property>
- <property name="singleStep">
- <double>10.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>Focal Length (mm)</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QDoubleSpinBox" name="guideScopeFocalIN">
- <property name="minimum">
- <double>1.000000000000000</double>
- </property>
- <property name="maximum">
- <double>100000.000000000000000</double>
- </property>
- <property name="singleStep">
- <double>10.000000000000000</double>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" name="BottomLayout">
- <item>
- <widget class="QPushButton" name="saveB">
- <property name="toolTip">
- <string>Save telescope information in confi