Commit dd076c04 authored by Jasem Mutlaq's avatar Jasem Mutlaq
Browse files

Initial work on PHD2 support in Ekos

parent 25b4a0ec
......@@ -100,6 +100,7 @@ if (CFITSIO_FOUND)
ekos/sequencejob.cpp
ekos/focus.cpp
ekos/guide.cpp
ekos/phd2.cpp
ekos/align.cpp
ekos/mount.cpp
ekos/dome.cpp
......
......@@ -66,6 +66,12 @@ public:
void setOptionsWidget(KPageWidgetItem *ops) { ekosOption = ops; }
void addObjectToScheduler(SkyObject *object);
Ekos::Capture *captureModule() { return captureProcess;}
Ekos::Focus *focusModule() { return focusProcess;}
Ekos::Guide *guideModule() { return guideProcess;}
Ekos::Align *alignModule() { return alignProcess;}
Ekos::Mount *mountModule() { return mountProcess;}
/** @defgroup EkosDBusInterface Ekos DBus Interface
* EkosManager interface provides advanced scripting capabilities to establish and shutdown Ekos services.
*/
......@@ -184,12 +190,6 @@ public slots:
void processNewNumber(INumberVectorProperty *nvp);
void processNewText(ITextVectorProperty *tvp);
Ekos::Capture *captureModule() { return captureProcess;}
Ekos::Focus *focusModule() { return focusProcess;}
Ekos::Guide *guideModule() { return guideProcess;}
Ekos::Align *alignModule() { return alignProcess;}
Ekos::Mount *mountModule() { return mountProcess;}
protected slots:
void updateLog();
......
......@@ -14,6 +14,8 @@
#include "guide/gmath.h"
#include "guide/guider.h"
#include "phd2.h"
#include "Options.h"
#include <KMessageBox>
......@@ -21,6 +23,8 @@
#include <KLocalizedString>
#include "indi/driverinfo.h"
#include "indi/clientmanager.h"
#include "fitsviewer/fitsviewer.h"
#include "fitsviewer/fitsview.h"
......@@ -57,8 +61,6 @@ Guide::Guide() : QWidget()
tabLayout->addWidget(tabWidget);
guiderStage = CALIBRATION_STAGE;
pmath = new cgmath();
connect(pmath, SIGNAL(newAxisDelta(double,double)), this, SIGNAL(newAxisDelta(double,double)));
......@@ -82,6 +84,11 @@ Guide::Guide() : QWidget()
foreach(QString filter, FITSViewer::filterTypes)
filterCombo->addItem(filter);
phd2 = new PHD2();
connect(phd2, SIGNAL(newLog(QString)), this, SLOT(appendLogText(QString)));
phd2->connectPHD2();
}
Guide::~Guide()
......@@ -89,6 +96,7 @@ Guide::~Guide()
delete guider;
delete calibration;
delete pmath;
delete phd2;
}
void Guide::addCCD(ISD::GDInterface *newCCD, bool isPrimaryGuider)
......@@ -110,6 +118,8 @@ void Guide::addCCD(ISD::GDInterface *newCCD, bool isPrimaryGuider)
guiderCombo->setCurrentIndex(0);
}
setGuiderProcess(Options::useEkosGuider() ? GUIDE_INTERNAL : GUIDE_PHD2);
//if (currentCCD->hasGuideHead())
// addGuideHead(newCCD);
......@@ -141,7 +151,7 @@ bool Guide::setCCD(QString device)
void Guide::checkCCD(int ccdNum)
{
if (ccdNum == -1)
ccdNum = guiderCombo->currentIndex();
ccdNum = guiderCombo->currentIndex();
if (ccdNum <= CCDs.count())
{
......@@ -162,19 +172,51 @@ void Guide::checkCCD(int ccdNum)
void Guide::addGuideHead(ISD::GDInterface *ccd)
{
currentCCD = (ISD::CCD *) ccd;
currentCCD = (ISD::CCD *) ccd;
CCDs.append(currentCCD);
CCDs.append(currentCCD);
// Let's just make sure
//if (currentCCD->hasGuideHead())
//{
// guiderCombo->clear();
guiderCombo->addItem(currentCCD->getDeviceName() + QString(" Guider"));
//useGuideHead = true;
checkCCD(0);
//}
guiderCombo->addItem(currentCCD->getDeviceName() + QString(" Guider"));
checkCCD(0);
setGuiderProcess(Options::useEkosGuider() ? GUIDE_INTERNAL : GUIDE_PHD2);
}
void Guide::setGuiderProcess(int guiderProcess)
{
// Don't do anything unless we have a CCD and it is online
if (currentCCD == NULL || currentCCD->isConnected() == false)
return;
if (guiderProcess == GUIDE_PHD2)
{
// Disable calibration tab
tabWidget->setTabEnabled(0, false);
// Enable guide tab
tabWidget->setTabEnabled(1, true);
// Set current tab to guide
tabWidget->setCurrentIndex(1);
guider->setPHD2(phd2);
// Do not receive BLOBs from the driver
currentCCD->getDriverInfo()->getClientManager()->setBLOBMode(B_NEVER, currentCCD->getDeviceName(), useGuideHead ? "CCD2" : "CCD1");
}
else
{
// Enable calibration tab
tabWidget->setTabEnabled(0, true);
// Disable guide tab?
// TODO: Check if calibration is already complete, then no need to disable guiding tab
tabWidget->setTabEnabled(1, false);
// Set current tab to calibration
tabWidget->setCurrentIndex(0);
guider->setPHD2(NULL);
// Receive BLOBs from the driver
currentCCD->getDriverInfo()->getClientManager()->setBLOBMode(B_ALSO, currentCCD->getDeviceName(), useGuideHead ? "CCD2" : "CCD1");
}
}
void Guide::syncCCDInfo()
......@@ -491,7 +533,6 @@ void Guide::newFITS(IBLOB *bp)
}
void Guide::appendLogText(const QString &text)
{
......@@ -708,49 +749,90 @@ void Guide::updateGuideDriver(double delta_ra, double delta_dec)
bool Guide::isCalibrationComplete()
{
return calibration->isCalibrationComplete();
if (Options::useEkosGuider())
return calibration->isCalibrationComplete();
else
return phd2->isCalibrationComplete();
}
bool Guide::isCalibrationSuccessful()
{
return calibration->isCalibrationSuccessful();
if (Options::useEkosGuider())
return calibration->isCalibrationSuccessful();
else
return phd2->isCalibrationSuccessful();
}
bool Guide::startCalibration()
{
return calibration->startCalibration();
if (Options::useEkosGuider())
return calibration->startCalibration();
else
return phd2->startGuiding();
}
bool Guide::stopCalibration()
{
return calibration->stopCalibration();
if (Options::useEkosGuider())
return calibration->stopCalibration();
else
return phd2->stopGuiding();
}
bool Guide::isCalibrating()
{
if (Options::useEkosGuider())
return calibration->isCalibrating();
else
return phd2->isCalibrating();
}
bool Guide::isGuiding()
{
return guider->isGuiding();
if (Options::useEkosGuider())
return guider->isGuiding();
else
return phd2->isGuiding();
}
bool Guide::startGuiding()
{
return guider->start();
if (Options::useEkosGuider())
return guider->start();
else
return phd2->startGuiding();
}
bool Guide::stopGuiding()
{
isSuspended=false;
return guider->abort(true);
if (Options::useEkosGuider())
return guider->abort(true);
else
return phd2->stopGuiding();
}
void Guide::setSuspended(bool enable)
{
if (enable == isSuspended || (enable && guider->isGuiding() == false))
if (enable == isSuspended || (enable && isGuiding() == false))
return;
isSuspended = enable;
if (isSuspended == false)
capture();
if (isSuspended)
{
if (Options::usePHD2Guider())
phd2->pauseGuiding();
}
else
{
if (Options::useEkosGuider())
capture();
else
phd2->startGuiding();
}
if (isSuspended)
appendLogText(i18n("Guiding suspended."));
......@@ -835,13 +917,20 @@ QList<double> Guide::getGuidingDeviation()
void Guide::startAutoCalibrateGuiding()
{
connect(calibration, SIGNAL(calibrationCompleted(bool)), this, SLOT(checkAutoCalibrateGuiding(bool)));
calibration->startCalibration();
if (Options::useEkosGuider())
connect(calibration, SIGNAL(calibrationCompleted(bool)), this, SLOT(checkAutoCalibrateGuiding(bool)));
else
connect(phd2, SIGNAL(calibrationCompleted(bool)), this, SLOT(checkAutoCalibrateGuiding(bool)));
startCalibration();
}
void Guide::checkAutoCalibrateGuiding(bool successful)
{
calibration->disconnect(this);
if (Options::useEkosGuider())
disconnect(calibration, SIGNAL(calibrationCompleted(bool)), this, SLOT(checkAutoCalibrateGuiding(bool)));
else
disconnect(phd2, SIGNAL(calibrationCompleted(bool)), this, SLOT(checkAutoCalibrateGuiding(bool)));
if (successful)
{
......@@ -856,7 +945,7 @@ void Guide::checkAutoCalibrateGuiding(bool successful)
void Guide::updateCCDBin(int index)
{
if (currentCCD == NULL)
if (currentCCD == NULL && Options::usePHD2Guider())
return;
ISD::CCDChip *targetChip = currentCCD->getChip(useGuideHead ? ISD::CCDChip::GUIDE_CCD : ISD::CCDChip::PRIMARY_CCD);
......
......@@ -30,6 +30,8 @@ class FITSData;
namespace Ekos
{
class PHD2;
/**
*@class Guide
*@short Performs calibration and autoguiding using an ST4 port or directly via the INDI driver.
......@@ -47,6 +49,7 @@ public:
~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.
......@@ -73,6 +76,11 @@ public:
*/
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.
*/
......@@ -167,6 +175,13 @@ public:
*/
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, bool isPrimaryGuider);
......@@ -178,7 +193,6 @@ public:
void syncTelescopeInfo();
void syncCCDInfo();
void appendLogText(const QString &);
void clearLog();
void setDECSwap(bool enable);
......@@ -236,10 +250,12 @@ public slots:
void startAutoCalibrateGuiding();
void checkAutoCalibrateGuiding(bool successful);
void viewerClosed();
void viewerClosed();
void dither();
void setSuspended(bool enable);
void dither();
void setSuspended(bool enable);
void appendLogText(const QString &);
protected slots:
void updateCCDBin(int index);
......@@ -273,14 +289,14 @@ private:
QTabWidget *tabWidget;
GuiderStage guiderStage;
cgmath *pmath;
rcalibration *calibration;
rguider *guider;
PHD2 *phd2;
bool useGuideHead;
bool isSuspended;
bool phd2Connected;
bool useDarkFrame;
double darkExposure;
......
......@@ -22,6 +22,7 @@
#include "scroll_graph.h"
#include "gmath.h"
#include "fitsviewer/fitsview.h"
#include "../phd2.h"
#include "../ekosmanager.h"
#include "kstars.h"
......@@ -41,7 +42,7 @@ rguider::rguider(cgmath *mathObject, Ekos::Guide *parent)
pmain_wnd = parent;
pimage = NULL;
phd2 = NULL;
targetChip = NULL;
m_useRapidGuide = false;
......@@ -79,6 +80,8 @@ rguider::rguider(cgmath *mathObject, Ekos::Guide *parent)
connect( ui.spinBox_MinPulseDEC, SIGNAL(editingFinished()), this, SLOT(onInputParamChanged()) );
connect( ui.rapidGuideCheck, SIGNAL(toggled(bool)), this, SLOT(onRapidGuideChanged(bool)));
connect( ui.connectPHD2B, SIGNAL(clicked()), this, SLOT(connectPHD2()));
connect(ui.captureB, SIGNAL(clicked()), this, SLOT(capture()));
connect( ui.pushButton_StartStop, SIGNAL(clicked()), this, SLOT(onStartStopButtonClick()) );
......@@ -360,7 +363,8 @@ void rguider::setTargetChip(ISD::CCDChip *chip)
{
targetChip = chip;
targetChip->getFrame(&fx, &fy, &fw, &fh);
ui.subFrameCheck->setEnabled(targetChip->canSubframe());
if (phd2 == NULL)
ui.subFrameCheck->setEnabled(targetChip->canSubframe());
}
bool rguider::start()
......@@ -385,6 +389,21 @@ bool rguider::start()
if (pimage)
disconnect(pimage, SIGNAL(guideStarSelected(int,int)), 0, 0);
if (phd2)
{
phd2->startGuiding();
m_isStarted = true;
m_useRapidGuide = ui.rapidGuideCheck->isChecked();
pmain_wnd->setSuspended(false);
ui.pushButton_StartStop->setText( i18n("Stop") );
pmain_wnd->appendLogText(i18n("Autoguiding started."));
return true;
}
logFile.open(QIODevice::WriteOnly | QIODevice::Text);
QTextStream out(&logFile);
out << "Guiding rate,x15 arcsec/sec: " << ui.spinBox_GuideRate->value() << endl;
......@@ -422,6 +441,9 @@ bool rguider::start()
bool rguider::stop()
{
if (phd2)
phd2->stopGuiding();
if (pimage)
connect(pimage, SIGNAL(guideStarSelected(int,int)), this, SLOT(guideStarSelected(int,int)));
ui.pushButton_StartStop->setText( i18n("Start Autoguide") );
......@@ -777,7 +799,8 @@ void rguider::setGuideOptions(int boxSize, const QString & algorithm, bool useSu
break;
}
ui.subFrameCheck->setChecked(useSubFrame);
if (phd2 == NULL)
ui.subFrameCheck->setChecked(useSubFrame);
ui.rapidGuideCheck->setChecked(useRapidGuide);
}
......@@ -787,5 +810,68 @@ void rguider::setDither(bool enable, double value)
if (enable && value > 0)
ui.ditherPixels->setValue(value);
}
void rguider::setPHD2(Ekos::PHD2 *phd)
{
// If we already have PHD2 set but we are asked to unset it then we shall disconnect all signals first
if (phd2 && phd == NULL)
phd2->disconnect();
phd2 = phd;
bool enable = (phd2 == NULL) ? true : false;
if (phd2)
{
if (phd2->isConnected())
setPHD2Connected();
else
setPHD2Disconnected();
connect(phd2, SIGNAL(connected()), this, SLOT(setPHD2Connected()), Qt::UniqueConnection);
connect(phd2, SIGNAL(disconnected()), this, SLOT(setPHD2Disconnected()), Qt::UniqueConnection);
}
ui.connectPHD2B->setHidden(enable);
ui.pushButton_StartStop->setEnabled(enable);
ui.controlGroup->setEnabled(enable);
ui.infoGroup->setEnabled(enable);
ui.captureB->setEnabled(enable);
ui.subFrameCheck->setEnabled(enable);
ui.rapidGuideCheck->setEnabled(enable);
ui.comboBox_SquareSize->setEnabled(enable);
ui.comboBox_ThresholdAlg->setEnabled(enable);
ui.ditherCheck->setEnabled(enable);
ui.ditherPixels->setEnabled(enable);
}
void rguider::connectPHD2()
{
if (phd2)
{
if (phd2->isConnected())
phd2->disconnectPHD2();
else
phd2->connectPHD2();
}
}
void rguider::setPHD2Connected()
{
ui.connectPHD2B->setText(i18n("Disconnect PHD2"));
ui.pushButton_StartStop->setEnabled(true);
ui.ditherCheck->setEnabled(true);
ui.ditherPixels->setEnabled(true);
}
void rguider::setPHD2Disconnected()
{
ui.connectPHD2B->setText(i18n("Connect PHD2"));
ui.pushButton_StartStop->setEnabled(false);
ui.ditherCheck->setEnabled(false);
ui.ditherPixels->setEnabled(false);
}
......@@ -13,6 +13,7 @@
#define GUIDER_H
#include <QtGui>
#include "common.h"
#include "ui_guider.h"
#include "scroll_graph.h"
......@@ -54,8 +55,13 @@ public:
bool useSubFrame();
bool useRapidGuide();
void setPHD2(Ekos::PHD2 *phd);
public slots:
void setDECSwap(bool enable);
void connectPHD2();
void setPHD2Connected();
void setPHD2Disconnected();
protected slots:
void onXscaleChanged( int i );
......@@ -80,6 +86,7 @@ signals:
private:
cgmath *pmath;
Ekos::Guide *pmain_wnd;
Ekos::PHD2 *phd2;
custom_drawer *pDriftOut;
cscroll_graph *drift_graph;
......
......@@ -37,7 +37,7 @@
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QGroupBox" name="groupBox_Drift">
<widget class="QGroupBox" name="driftGraphicsGroup">
<property name="title">
<string>Drift graphics</string>
</property>
......@@ -157,7 +157,7 @@
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox_Info">
<widget class="QGroupBox" name="infoGroup">
<property name="title">
<string>Info</string>
</property>
......@@ -462,7 +462,10 @@
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_Configuration">
<widget class="QGroupBox" name="setupGroup">
<property name="enabled">
<bool>true</bool>
</property>
<property name="title">
<string>Setup</string>
</property>
......@@ -473,6 +476,9 @@
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<widget class="QPushButton" name="captureB">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Capture</string>
</property>
......@@ -592,13 +598,23 @@
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="connectPHD2B">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Connect PHD2</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox_Control">
<widget class="QGroupBox" name="controlGroup">
<property name="title">
<string>Control</string>
</property>
......
......@@ -20,7 +20,7 @@
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QGroupBox" name="groupBox_3">
<widget class="QGroupBox" name="calibrationChecklistGroup">
<property name="title">
<string>Calibration Checklist</string>
</property>
......@@ -138,7 +138,7 @@
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_ReticleCalibration_2">
<widget class="QGroupBox" name="calibrationOptionsGroup">
<property name="title">
<string>Calibration Options</string>
</property>
......