Commit 120af427 authored by Jasem Mutlaq's avatar Jasem Mutlaq
Browse files

More progress on migrating guide stuff

parent af6d5f38
......@@ -177,14 +177,16 @@ if (INDI_FOUND)
# Guide
ekos/guide/guide.cpp
ekos/guide/guideinterface.cpp
ekos/guide/scroll_graph.cpp
# Internal Guide
ekos/guide/internalguide/common.cpp
ekos/guide/internalguide/gmath.cpp
ekos/guide/internalguide/internalguider.cpp
ekos/guide/internalguide/guider.cpp
ekos/guide/internalguide/matr.cpp
ekos/guide/internalguide/rcalibration.cpp
ekos/guide/internalguide/scroll_graph.cpp
ekos/guide/internalguide/rcalibration.cpp
ekos/guide/internalguide/vect.cpp
# External Guide
ekos/guide/externalguide/phd2.cpp
)
endif(CFITSIO_FOUND)
......
......@@ -93,8 +93,7 @@ Capture::Capture()
dustCapLightEnabled = lightBoxLightEnabled = false;
//isAutoGuiding = false;
guideDither = false;
//isAutoGuiding = false;
isAutoFocus = false;
autoFocusStatus = false;
resumeAlignmentAfterFlip= false;
......@@ -176,8 +175,7 @@ Capture::Capture()
seqCurrentCount = 0;
seqDelay = 0;
fileHFR=0;
useGuideHead = false;
guideDither = false;
useGuideHead = false;
firstAutoFocus = true;
foreach(QString filter, FITSViewer::filterTypes)
......@@ -1115,7 +1113,7 @@ bool Capture::resumeSequence()
emit suspendGuiding(false);
//if (isAutoGuiding && guideDither && activeJob->getFrameType() == FRAME_LIGHT)
if (guideState == GUIDE_GUIDING && guideDither && activeJob->getFrameType() == FRAME_LIGHT)
if (guideState == GUIDE_GUIDING && Options::useDither() && activeJob->getFrameType() == FRAME_LIGHT)
{
secondsLabel->setText(i18n("Dithering..."));
//emit exposureComplete();
......@@ -1963,11 +1961,6 @@ void Capture::setGuideDeviation(double delta_ra, double delta_dec)
}
}
void Capture::setGuideDither(bool enable)
{
guideDither = enable;
}
void Capture::setFocusStatus(FocusState state)
{
focusState = state;
......
......@@ -359,12 +359,6 @@ public slots:
*/
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.
*/
......@@ -531,10 +525,6 @@ private:
bool deviationDetected;
bool spikeDetected;
// Dither
bool guideDither;
//bool isAutoGuiding;
// Autofocus
bool isAutoFocus;
bool autoFocusStatus;
......
......@@ -7,10 +7,11 @@ namespace Ekos
{
// Guide States
static const QStringList guideStates = { I18N_NOOP("Idle"), I18N_NOOP("Calibrating"), I18N_NOOP("Calibration successful"), I18N_NOOP("Calibration error"), I18N_NOOP("Guiding"),
I18N_NOOP("Aborted"), I18N_NOOP("Suspended"), I18N_NOOP("Dithering"), I18N_NOOP("Dithering Successful"), I18N_NOOP("Dithering error")};
static const QStringList guideStates = { I18N_NOOP("Idle"), I18N_NOOP("Connected"), I18N_NOOP("Disconnected"), I18N_NOOP("Calibrating"), I18N_NOOP("Calibration successful"),
I18N_NOOP("Calibration error"), I18N_NOOP("Guiding"), I18N_NOOP("Aborted"), I18N_NOOP("Suspended"), I18N_NOOP("Dithering"),
I18N_NOOP("Dithering successful"), I18N_NOOP("Dithering error")};
typedef enum { GUIDE_IDLE, GUIDE_CALIBRATING, GUIDE_CALIBRATION_SUCESS, GUIDE_CALIBRATION_ERROR, GUIDE_GUIDING,
typedef enum { GUIDE_IDLE, GUIDE_CONNECTED, GUIDE_DISCONNECTED, GUIDE_CALIBRATING, GUIDE_CALIBRATION_SUCESS, GUIDE_CALIBRATION_ERROR, GUIDE_GUIDING,
GUIDE_ABORTED, GUIDE_SUSPENDED, GUIDE_DITHERING, GUIDE_DITHERING_SUCCESS, GUIDE_DITHERING_ERROR } GuideState;
const QString & getGuideStatusString(GuideState state);
......
......@@ -71,7 +71,7 @@ PHD2::~PHD2()
}
void PHD2::connectPHD2()
void PHD2::Connect()()
{
if (connection == DISCONNECTED)
{
......@@ -264,7 +264,6 @@ void PHD2::processPHD2Event(const QJsonObject &jsonEvent)
emit connected();
}
emit newLog(i18n("PHD2: Guiding Started."));
//emit autoGuidingToggled(true);
emit newStatus(Ekos::GUIDE_GUIDING);
break;
......@@ -467,9 +466,8 @@ void PHD2::setEquipmentConnected(bool enable)
sendJSONRPCRequest("set_connected", args);
}
bool PHD2::startGuiding()
bool PHD2::guide()
{
if (connection != EQUIPMENT_CONNECTED)
{
emit newLog(i18n("PHD2 Error: Equipment not connected."));
......@@ -493,7 +491,7 @@ bool PHD2::startGuiding()
return true;
}
bool PHD2::stopGuiding()
bool PHD2::stop()
{
if (connection != EQUIPMENT_CONNECTED)
{
......@@ -505,7 +503,7 @@ bool PHD2::stopGuiding()
return true;
}
bool PHD2::pauseGuiding()
bool PHD2::suspend()
{
if (connection != EQUIPMENT_CONNECTED)
{
......@@ -526,7 +524,7 @@ bool PHD2::pauseGuiding()
}
bool PHD2::resumeGuiding()
bool PHD2::resume()
{
if (connection != EQUIPMENT_CONNECTED)
{
......@@ -579,11 +577,12 @@ bool PHD2::isConnected()
return (connection >= CONNECTED);
}
void PHD2::setCCDMountParams(double ccd_pix_w, double ccd_pix_h, double mount_focal)
void PHD2::setCCDMountParams(double ccd_pix_w, double ccd_pix_h, double mount_aperture, double mount_focal)
{
ccd_pixel_width = ccd_pix_w/1000.0;
ccd_pixel_height= ccd_pix_h/1000.0;
focal = mount_focal;
aperture = mount_aperture;
}
}
......
......@@ -13,7 +13,7 @@
#include <QAbstractSocket>
#include <QJsonArray>
#include "guide.h"
#include "../guideinterface.h"
class QTcpSocket;
......@@ -24,9 +24,10 @@ namespace Ekos
* @class PHD2
* Uses external PHD2 for guiding.
*
* @authro Jasem Mutlaq
* @author Jasem Mutlaq
* @version 1.1
*/
class PHD2 : public QObject
class PHD2 : public GuideInterface
{
Q_OBJECT
......@@ -41,45 +42,25 @@ public:
PHD2();
~PHD2();
void connectPHD2();
void disconnectPHD2();
void Connect() override;
void Disconnect() override;
bool isConnected();
bool isCalibrating() { return state == CALIBRATING; }
bool isCalibrationComplete() { return state > CALIBRATING; }
bool isCalibrationSuccessful() { return state >= CALIBRATION_SUCCESSFUL; }
bool isGuiding() { return state == GUIDING; }
bool isDithering() { return state == DITHERING; }
void setCCDMountParams(double ccd_pix_w, double ccd_pix_h, double mount_focal);
void setEquipmentConnected(bool enable);
bool startGuiding();
bool stopGuiding();
bool pauseGuiding();
bool resumeGuiding();
bool dither(double pixels);
bool calibrate() override;
bool guide() override;
bool stop() override;
bool suspend() override;
bool resume() override;
bool dither(double pixels) override;
private slots:
void readPHD2();
void displayError(QAbstractSocket::SocketError socketError);
signals:
void newLog(const QString &);
void connected();
void disconnected();
//void ditherComplete();
//void ditherFailed();
void newAxisDelta(double delta_ra, double delta_dec);
//void autoGuidingToggled(bool);
//void guideReady();
void newStatus(Ekos::GuideState);
void displayError(QAbstractSocket::SocketError socketError);
private:
void setEquipmentConnected(bool enable);
void sendJSONRPCRequest(const QString & method, const QJsonArray args = QJsonArray());
void processJSON(const QJsonObject &jsonObj);
......@@ -96,7 +77,7 @@ private:
PHD2Connection connection;
PHD2Event event;
double ccd_pixel_width, ccd_pixel_height, focal;
double ccd_pixel_width, ccd_pixel_height, aperture, focal;
};
}
......
......@@ -19,18 +19,16 @@
#include "Options.h"
#include "guide/gmath.h"
#include "guide/guider.h"
#include "phd2.h"
#include "internalguide/internalguider.h"
#include "externalguide/phd2.h"
#include "darklibrary.h"
#include "ekos/auxiliary/darklibrary.h"
#include "indi/driverinfo.h"
#include "indi/clientmanager.h"
#include "fitsviewer/fitsviewer.h"
#include "fitsviewer/fitsview.h"
#include "guide/rcalibration.h"
#include "guideadaptor.h"
#include "kspaths.h"
......@@ -48,78 +46,112 @@ Guide::Guide() : QWidget()
currentCCD = NULL;
currentTelescope = NULL;
ccd_hor_pixel = ccd_ver_pixel = focal_length = aperture = -1;
useGuideHead = false;
rapidGuideReticleSet = false;
isSuspended = false;
AODriver= NULL;
GuideDriver=NULL;
calibration=NULL;
guider=NULL;
state = GUIDE_IDLE;
ccd_hor_pixel = ccd_ver_pixel = focal_length = aperture = -1;
guideDeviationRA = guideDeviationDEC = 0;
useGuideHead = false;
rapidGuideReticleSet = false;
// Exposure
exposureIN->setValue(Options::guideExposure());
connect(exposureIN, SIGNAL(editingFinished()), this, SLOT(saveDefaultGuideExposure()));
// Guiding Box Size
boxSizeCombo->setCurrentIndex(Options::guideSquareSizeIndex());
connect(boxSizeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateTrackingBoxSize(int)));
// TODO must develop a parent abstract GuideProcess class that is then inherited by both the internal guider and PHD2 and any additional future guiders
// It should provide the interface to hook its actions and results here instead of this mess.
pmath = new cgmath();
// Guider CCD Selection
connect(guiderCombo, SIGNAL(activated(QString)), this, SLOT(setDefaultCCD(QString)));
connect(guiderCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(checkCCD(int)));
connect(pmath, SIGNAL(newAxisDelta(double,double)), this, SIGNAL(newAxisDelta(double,double)));
connect(pmath, SIGNAL(newAxisDelta(double,double)), this, SLOT(updateGuideDriver(double,double)));
connect(pmath, SIGNAL(newStarPosition(QVector3D,bool)), this, SLOT(setStarPosition(QVector3D,bool)));
// Dark Frame Check
darkFrameCheck->setChecked(Options::useGuideDarkFrame());
connect(darkFrameCheck, SIGNAL(toggled(bool)), this, SLOT(setDarkFrameEnabled(bool)));
calibration = new internalCalibration(pmath, this);
// ST4 Selection
connect(ST4Combo, SIGNAL(currentIndexChanged(int)), this, SLOT(newST4(int)));
connect(ST4Combo, SIGNAL(activated(QString)), this, SLOT(setDefaultST4(QString)));
connect(calibration, SIGNAL(newStatus(Ekos::GuideState)), this, SLOT(setStatus(Ekos::GuideState)));
// Binning Combo Selection
connect(binningCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateCCDBin(int)));
guider = new internalGuider(pmath, this);
// Drift Graph scales
connect( spinBox_XScale, SIGNAL(valueChanged(int)), this, SLOT(onXscaleChanged(int)) );
connect( spinBox_YScale, SIGNAL(valueChanged(int)), this, SLOT(onYscaleChanged(int)) );
connect(guider, SIGNAL(ditherToggled(bool)), this, SIGNAL(ditherToggled(bool)));
//connect(guider, SIGNAL(autoGuidingToggled(bool)), this, SIGNAL(autoGuidingToggled(bool)));
//connect(guider, SIGNAL(ditherComplete()), this, SIGNAL(ditherComplete()));
connect(guider, SIGNAL(newStatus(Ekos::GuideState)), this, SLOT(setStatus(Ekos::GuideState)));
connect(guider, SIGNAL(newProfilePixmap(QPixmap &)), this, SIGNAL(newProfilePixmap(QPixmap &)));
connect(guider, SIGNAL(newStarPosition(QVector3D,bool)), this, SLOT(setStarPosition(QVector3D,bool)));
tabWidget->addTab(calibration, calibration->windowTitle());
tabWidget->addTab(guider, guider->windowTitle());
tabWidget->setTabEnabled(1, false);
// MOVE THIS TO GUIDE OPTIONS
connect( ui.comboBox_ThresholdAlg, SIGNAL(activated(int)), this, SLOT(onThresholdChanged(int)) );
connect( ui.rapidGuideCheck, SIGNAL(toggled(bool)), this, SLOT(onRapidGuideChanged(bool)));
connect(ST4Combo, SIGNAL(currentIndexChanged(int)), this, SLOT(newST4(int)));
connect(ST4Combo, SIGNAL(activated(QString)), this, SLOT(setDefaultST4(QString)));
// Guiding Rate - Advisory only
connect( spinBox_GuideRate, SIGNAL(valueChanged(double)), this, SLOT(onInfoRateChanged(double)) );
connect(guiderCombo, SIGNAL(activated(QString)), this, SLOT(setDefaultCCD(QString)));
connect(guiderCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(checkCCD(int)));
// RA/DEC Enable directions
connect( checkBox_DirRA, SIGNAL(stateChanged(int)), this, SLOT(onEnableDirRA(int)) );
connect( checkBox_DirDEC, SIGNAL(stateChanged(int)), this, SLOT(onEnableDirDEC(int)) );
connect(binningCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateCCDBin(int)));
// Declination Swap
connect(swapCheck, SIGNAL(toggled(bool)), this, SLOT(setDECSwap(bool)));
// PID Control - Propotional Gain
connect( spinBox_PropGainRA, SIGNAL(editingFinished()), this, SLOT(onInputParamChanged()) );
connect( spinBox_PropGainDEC, SIGNAL(editingFinished()), this, SLOT(onInputParamChanged()) );
// PID Control - Integral Gain
connect( spinBox_IntGainRA, SIGNAL(editingFinished()), this, SLOT(onInputParamChanged()) );
connect( spinBox_IntGainDEC, SIGNAL(editingFinished()), this, SLOT(onInputParamChanged()) );
// PID Control - Derivative Gain
connect( spinBox_DerGainRA, SIGNAL(editingFinished()), this, SLOT(onInputParamChanged()) );
connect( spinBox_DerGainDEC, SIGNAL(editingFinished()), this, SLOT(onInputParamChanged()) );
// Max Pulse Duration (ms)
connect( spinBox_MaxPulseRA, SIGNAL(editingFinished()), this, SLOT(onInputParamChanged()) );
connect( spinBox_MaxPulseDEC, SIGNAL(editingFinished()), this, SLOT(onInputParamChanged()) );
// Min Pulse Duration (ms)
connect( spinBox_MinPulseRA, SIGNAL(editingFinished()), this, SLOT(onInputParamChanged()) );
connect( spinBox_MinPulseDEC, SIGNAL(editingFinished()), this, SLOT(onInputParamChanged()) );
// Image Filters
foreach(QString filter, FITSViewer::filterTypes)
filterCombo->addItem(filter);
darkFrameCheck->setChecked(Options::useGuideDarkFrame());
connect(darkFrameCheck, SIGNAL(toggled(bool)), this, SLOT(setDarkFrameEnabled(bool)));
phd2 = new PHD2();
connect(phd2, SIGNAL(newLog(QString)), this, SLOT(appendLogText(QString)));
connect(phd2, SIGNAL(newStatus(Ekos::GuideState)), this, SLOT(setStatus(Ekos::GuideState)));
connect(phd2, SIGNAL(newStatus(Ekos::GuideState)), guider, SLOT(toggleExternalGuideStateGUI(Ekos::GuideState)));
guiderType = static_cast<GuiderType>(Options::GuiderType());
switch (guiderType)
{
case GUIDE_INTERNAL:
guider= new InternalGuider();
break;
case GUIDE_PHD2:
guider = new PHD2();
break;
case GUIDE_LINGUIDER:
//guider = new LINGuider();
break;
}
connect(phd2, SIGNAL(newAxisDelta(double,double)), this, SIGNAL(newAxisDelta(double,double)));
//connect(phd2, SIGNAL(guideReady()), this, SIGNAL(guideReady()));
//connect(phd2, SIGNAL(autoGuidingToggled(bool)), this, SIGNAL(autoGuidingToggled(bool)));
//connect(phd2, SIGNAL(autoGuidingToggled(bool)), guider, SLOT(setGuideState(bool)));
//connect(phd2, SIGNAL(ditherComplete()), this, SIGNAL(ditherComplete()));
if (Options::usePHD2Guider())
phd2->connectPHD2();
state = GUIDE_IDLE;
connect(guider, SIGNAL(newStatus(Ekos::GuideState)), this, SLOT(setStatus(Ekos::GuideState)));
connect(guider, SIGNAL(newProfilePixmap(QPixmap &)), this, SIGNAL(newProfilePixmap(QPixmap &)));
connect(guider, SIGNAL(newStarPosition(QVector3D,bool)), this, SLOT(setStarPosition(QVector3D,bool)));
guider->Connect();
}
Guide::~Guide()
......@@ -1274,6 +1306,134 @@ bool Guide::selectAutoStar()
return true;
}
void Guide::onXscaleChanged( int i )
{
int rx, ry;
drift_graph->get_visible_ranges( &rx, &ry );
drift_graph->set_visible_ranges( i*drift_graph->get_grid_N(), ry );
// refresh if not started
if( state != GUIDE_GUIDING )
drift_graph->on_paint();
}
void Guide::onYscaleChanged( int i )
{
int rx, ry;
drift_graph->get_visible_ranges( &rx, &ry );
drift_graph->set_visible_ranges( rx, i*drift_graph->get_grid_N() );
// refresh if not started
if( state != GUIDE_GUIDING )
drift_graph->on_paint();
}
void internalGuider::onThresholdChanged( int index )
{
if( pmath )
pmath->setSquareAlgorithm( index );
}
// params changing stuff
void internalGuider::onInfoRateChanged( double val )
{
cproc_in_params *in_params;
if( !pmath )
return;
in_params = pmath->getInputParameters();
in_params->guiding_rate = val;
ui.l_RecommendedGain->setText( i18n("P: %1", QString().setNum(pmath->preCalculatePropotionalGain(in_params->guiding_rate), 'f', 2 )) );
}
void internalGuider::onEnableDirRA( int state )
{
cproc_in_params *in_params;
if( !pmath )
return;
in_params = pmath->getInputParameters();
in_params->enabled[GUIDE_RA] = (state == Qt::Checked);
}
void internalGuider::onEnableDirDEC( int state )
{
cproc_in_params *in_params;
if( !pmath )
return;
in_params = pmath->getInputParameters();
in_params->enabled[GUIDE_DEC] = (state == Qt::Checked);
}
void internalGuider::onInputParamChanged()
{
QObject *obj;
QSpinBox *pSB;
QDoubleSpinBox *pDSB;
cproc_in_params *in_params;
if( !pmath )
return;
obj = sender();
in_params = pmath->getInputParameters();
if( (pSB = dynamic_cast<QSpinBox *>(obj)) )
{
if( pSB == ui.spinBox_MaxPulseRA )
in_params->max_pulse_length[GUIDE_RA] = pSB->value();
else
if( pSB == ui.spinBox_MaxPulseDEC )
in_params->max_pulse_length[GUIDE_DEC] = pSB->value();
else
if( pSB == ui.spinBox_MinPulseRA )
in_params->min_pulse_length[GUIDE_RA] = pSB->value();
else
if( pSB == ui.spinBox_MinPulseDEC )
in_params->min_pulse_length[GUIDE_DEC] = pSB->value();
}
else
if( (pDSB = dynamic_cast<QDoubleSpinBox *>(obj)) )
{
if( pDSB == ui.spinBox_PropGainRA )
in_params->proportional_gain[GUIDE_RA] = pDSB->value();
else
if( pDSB == ui.spinBox_PropGainDEC )
in_params->proportional_gain[GUIDE_DEC] = pDSB->value();
else
if( pDSB == ui.spinBox_IntGainRA )
in_params->integral_gain[GUIDE_RA] = pDSB->value();
else
if( pDSB == ui.spinBox_IntGainDEC )
in_params->integral_gain[GUIDE_DEC] = pDSB->value();
else
if( pDSB == ui.spinBox_DerGainRA )
in_params->derivative_gain[GUIDE_RA] = pDSB->value();
else
if( pDSB == ui.spinBox_DerGainDEC )
in_params->derivative_gain[GUIDE_DEC] = pDSB->value();
}
}
}
......@@ -13,32 +13,34 @@
#include <QTimer>
#include <QtDBus/QtDBus>
#include "ekos.h"
#include "guide/common.h"
#include "guide.h"
#include "fitsviewer/fitscommon.h"
#include "ekos/ekos.h"
#include "indi/indistd.h"
#include "indi/inditelescope.h"
#include "indi/indiccd.h"
#include "guide.h"
#include "fitsviewer/fitscommon.h"
#include "ui_guide.h"
class QTabWidget;
class cgmath;
class internalCalibration;
class internalGuider;
class FITSData;
class ScrollGraph;
namespace Ekos
{
class PHD2;
class GuideInterface;
/**
*@class Guide