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

Major overhaul of guiding module to make it work better with the FITSView...

Major overhaul of guiding module to make it work better with the FITSView tracking box that is used by all modules now. Use Dark Library to capture darks whenever necessary. Tweaked GUI a bit. Subframing on different binning and box size variations work a lot more reliably now
parent 18e7dcec
......@@ -47,9 +47,9 @@ Guide::Guide() : QWidget()
currentCCD = NULL;
currentTelescope = NULL;
ccd_hor_pixel = ccd_ver_pixel = focal_length = aperture = -1;
useGuideHead = false;
useGuideHead = false;
rapidGuideReticleSet = false;
isSuspended = false;
isSuspended = false;
AODriver= NULL;
GuideDriver=NULL;
calibration=NULL;
......@@ -66,24 +66,29 @@ Guide::Guide() : QWidget()
exposureIN->setValue(Options::guideExposure());
connect(exposureIN, SIGNAL(editingFinished()), this, SLOT(saveDefaultGuideExposure()));
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();
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)));
calibration = new rcalibration(pmath, this);
calibration = new internalCalibration(pmath, this);
connect(calibration, SIGNAL(newStatus(Ekos::GuideState)), this, SLOT(setStatus(Ekos::GuideState)));
guider = new rguider(pmath, this);
guider = new internalGuider(pmath, this);
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());
......@@ -217,7 +222,7 @@ void Guide::checkCCD(int ccdNum)
}
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;
......@@ -355,7 +360,7 @@ void Guide::updateGuideParams()
if (ccd_hor_pixel != -1 && ccd_ver_pixel != -1 && focal_length != -1 && aperture != -1)
{
pmath->set_guider_params(ccd_hor_pixel, ccd_ver_pixel, aperture, focal_length);
pmath->setGuiderParameters(ccd_hor_pixel, ccd_ver_pixel, aperture, focal_length);
phd2->setCCDMountParams(ccd_hor_pixel, ccd_ver_pixel, focal_length);
int x,y,w,h;
......@@ -365,7 +370,7 @@ void Guide::updateGuideParams()
guider->setTargetChip(targetChip);
if (targetChip->getFrame(&x,&y,&w,&h))
pmath->set_video_params(w, h);
pmath->setVideoParameters(w, h);
guider->setInterface();
......@@ -434,11 +439,11 @@ bool Guide::capture()
}
//If calibrating, reset frame
if (calibration->getCalibrationStage() == rcalibration::CAL_CAPTURE_IMAGE)
if (calibration->getCalibrationStage() == internalCalibration::CAL_CAPTURE_IMAGE)
{
targetChip->resetFrame();
guider->setSubFramed(false);
}
}
targetChip->setCaptureMode(FITS_GUIDE);
targetChip->setFrameType(FRAME_LIGHT);
......@@ -476,7 +481,7 @@ void Guide::newFITS(IBLOB *bp)
// Do we need to take a dark frame?
if (Options::useGuideDarkFrame())
{
{
int x,y,w,h;
int binx,biny;
......@@ -497,8 +502,8 @@ void Guide::newFITS(IBLOB *bp)
DarkLibrary::Instance()->subtract(darkData, currentImage, targetChip->getCaptureFilter(), offsetX, offsetY);
else
{
if (calibration->useAutoStar() == false)
KMessageBox::information(NULL, i18n("If the guide camera is not equipped with a shutter, cover the telescope or camera in order to take a dark exposure."), i18n("Dark Exposure"), "dark_exposure_dialog_notification");
//if (calibration->useAutoStar() == false)
//KMessageBox::information(NULL, i18n("If the guide camera is not equipped with a shutter, cover the telescope or camera in order to take a dark exposure."), i18n("Dark Exposure"), "dark_exposure_dialog_notification");
DarkLibrary::Instance()->captureAndSubtract(targetChip, currentImage, exposureIN->value(), offsetX, offsetY);
}
......@@ -532,28 +537,40 @@ void Guide::setCaptureComplete()
FITSData *image_data = targetImage->getImageData();
Q_ASSERT(image_data);
pmath->set_image(targetImage);
guider->setImage(targetImage);
pmath->setImageView(targetImage);
guider->setImageView(targetImage);
//fv->show();
int subBinX=1, subBinY=1;
targetChip->getBinning(&subBinX, &subBinY);
// It should be false in case we do not need to process the image for motion
// which happens when we take an image for auto star selection.
if (calibration->setImage(targetImage) == false)
if (calibration->setImageView(targetImage) == false)
return;
if (isSuspended)
if (starCenter.x() == 0 && starCenter.y() == 0)
{
//capture();
int x,y,w,h;
targetChip->getFrame(&x,&y,&w,&h);
starCenter.setX(w/(2*subBinX));
starCenter.setY(h/(2*subBinY));
starCenter.setZ(subBinX);
}
syncTrackingBoxPosition();
if (isSuspended)
{
if (Options::guideLogging())
qDebug() << "Guide: Guider is suspended.";
return;
}
}
if (guider->isDithering())
{
pmath->do_processing();
pmath->performProcessing();
if (guider->dither() == false)
{
appendLogText(i18n("Dithering failed. Autoguiding aborted."));
......@@ -571,7 +588,7 @@ void Guide::setCaptureComplete()
else if (calibration->isCalibrating())
{
GuideDriver = ST4Driver;
pmath->do_processing();
pmath->performProcessing();
calibration->processCalibration();
if (calibration->isCalibrationComplete())
......@@ -671,9 +688,9 @@ void Guide::processRapidStarData(ISD::CCDChip *targetChip, double dx, double dy,
if (targetImage == NULL)
{
pmath->set_image(NULL);
guider->setImage(NULL);
calibration->setImage(NULL);
pmath->setImageView(NULL);
guider->setImageView(NULL);
calibration->setImageView(NULL);
}
if (rapidGuideReticleSet == false)
......@@ -681,8 +698,8 @@ void Guide::processRapidStarData(ISD::CCDChip *targetChip, double dx, double dy,
// Let's set reticle parameter on first capture to those of the star, then we check if there
// is any set
double x,y,angle;
pmath->get_reticle_params(&x, &y, &angle);
pmath->set_reticle_params(dx, dy, angle);
pmath->getReticleParameters(&x, &y, &angle);
pmath->setReticleParameters(dx, dy, angle);
rapidGuideReticleSet = true;
}
......@@ -690,7 +707,7 @@ void Guide::processRapidStarData(ISD::CCDChip *targetChip, double dx, double dy,
if (guider->isDithering())
{
pmath->do_processing();
pmath->performProcessing();
if (guider->dither() == false)
{
appendLogText(i18n("Dithering failed. Autoguiding aborted."));
......@@ -842,7 +859,7 @@ bool Guide::isGuiding()
}
bool Guide::startGuiding()
{
{
// This will handle both internal and external guiders
return guider->start();
......@@ -925,29 +942,29 @@ void Guide::setCalibrationAutoSquareSize(bool enable)
calibration->setCalibrationAutoSquareSize(enable);
}
void Guide::setCalibrationParams(int boxSize, int pulseDuration)
void Guide::setCalibrationPulseDuration(int pulseDuration)
{
calibration->setCalibrationParams(boxSize, pulseDuration);
calibration->setCalibrationPulseDuration(pulseDuration);
}
void Guide::setGuideBoxSize(int boxSize)
void Guide::setGuideBoxSizeIndex(int boxSize)
{
guider->setGuideOptions(boxSize, guider->getAlgorithm(), guider->useSubFrame(), guider->useRapidGuide());
boxSizeCombo->setCurrentIndex(boxSize);
}
void Guide::setGuideAlgorithm(const QString & algorithm)
{
guider->setGuideOptions(guider->getBoxSize(), algorithm, guider->useSubFrame(), guider->useRapidGuide());
guider->setGuideOptions(algorithm, guider->useSubFrame(), guider->useRapidGuide());
}
void Guide::setSubFrameEnabled(bool enable)
{
guider->setGuideOptions(guider->getBoxSize(), guider->getAlgorithm(), enable , guider->useRapidGuide());
guider->setGuideOptions(guider->getAlgorithm(), enable , guider->useRapidGuide());
}
void Guide::setGuideRapid(bool enable)
{
guider->setGuideOptions(guider->getBoxSize(), guider->getAlgorithm(), guider->useSubFrame() , enable);
guider->setGuideOptions(guider->getAlgorithm(), guider->useSubFrame() , enable);
}
void Guide::setDither(bool enable, double value)
......@@ -1062,8 +1079,6 @@ void Guide::updateCCDBin(int index)
targetChip->setBinning(index+1, index+1);
if (pmath)
pmath->setBinning(index+1, index+1);
}
void Guide::processCCDNumber(INumberVectorProperty *nvp)
......@@ -1091,12 +1106,12 @@ void Guide::checkExposureValue(ISD::CCDChip *targetChip, double exposure, IPStat
}
void Guide::setDarkFrameEnabled(bool enable)
{
{
Options::setUseGuideDarkFrame(enable);
if (enable && calibration && calibration->useAutoStar())
/*if (enable && calibration && calibration->useAutoStar())
appendLogText(i18n("Warning: In auto mode, you will not be asked to cover cameras unequipped with shutters in order to capture a dark frame. The dark frame capture will proceed without warning."
" You can capture dark frames with auto mode off and they shall be saved in the dark library for use when ever needed."));
" You can capture dark frames with auto mode off and they shall be saved in the dark library for use when ever needed."));*/
}
void Guide::saveDefaultGuideExposure()
......@@ -1104,6 +1119,65 @@ void Guide::saveDefaultGuideExposure()
Options::setGuideExposure(exposureIN->value());
}
void Guide::setStarPosition(const QVector3D &newCenter, bool updateNow)
{
starCenter.setX(newCenter.x());
starCenter.setY(newCenter.y());
if (newCenter.z() > 0)
starCenter.setZ(newCenter.z());
if (updateNow)
syncTrackingBoxPosition();
}
void Guide::syncTrackingBoxPosition()
{
ISD::CCDChip *targetChip = currentCCD->getChip(useGuideHead ? ISD::CCDChip::GUIDE_CCD : ISD::CCDChip::PRIMARY_CCD);
Q_ASSERT(targetChip);
int subBinX=1, subBinY=1;
targetChip->getBinning(&subBinX, &subBinY);
FITSView *targetImage = targetChip->getImage(FITS_GUIDE);
if (targetImage && starCenter.isNull() == false)
{
double boxSize = boxSizeCombo->currentText().toInt();
int x,y,w,h;
targetChip->getFrame(&x,&y,&w,&h);
// If box size is larger than image size, set it to lower index
if (boxSize/subBinX >= w || boxSize/subBinY >= h)
{
boxSizeCombo->setCurrentIndex(boxSizeCombo->currentIndex()-1);
return;
}
// If binning changed, update coords accordingly
if (subBinX != starCenter.z())
{
if (starCenter.z() > 0)
{
starCenter.setX(starCenter.x() * (starCenter.z()/subBinX));
starCenter.setY(starCenter.y() * (starCenter.z()/subBinY));
}
starCenter.setZ(subBinX);
}
QRect starRect = QRect( starCenter.x()-boxSize/(2*subBinX), starCenter.y()-boxSize/(2*subBinY), boxSize/subBinX, boxSize/subBinY);
targetImage->setTrackingBoxEnabled(true);
targetImage->setTrackingBox(starRect);
}
}
void Guide::updateTrackingBoxSize(int currentIndex)
{
Options::setGuideSquareSizeIndex(currentIndex);
syncTrackingBoxPosition();
}
}
......@@ -24,8 +24,8 @@
class QTabWidget;
class cgmath;
class rcalibration;
class rguider;
class internalCalibration;
class internalGuider;
class FITSData;
namespace Ekos
......@@ -35,9 +35,10 @@ class PHD2;
/**
*@class Guide
*@short Performs calibration and autoguiding using an ST4 port or directly via the INDI driver.
*@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.1
*@version 1.2
*/
class Guide : public QWidget, public Ui::Guide
{
......@@ -50,7 +51,7 @@ public:
~Guide();
enum GuiderStage { CALIBRATION_STAGE, GUIDE_STAGE };
enum GuiderProcess { GUIDE_INTERNAL, GUIDE_PHD2 };
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.
......@@ -140,16 +141,15 @@ public:
/** DBUS interface function.
* Set calibration parameters.
* @param boxSize box size in pixels around the guide star. The box size should be suitable for the size of the guide star selected.
* @param pulseDuration Pulse duration in milliseconds to use in the calibration steps.
*/
Q_SCRIPTABLE Q_NOREPLY void setCalibrationParams(int boxSize, int pulseDuration);
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 boxSize box size in pixels around the guide star. 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.
* @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 setGuideBoxSize(int boxSize);
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.
......@@ -198,12 +198,18 @@ public:
void clearLog();
void setDECSwap(bool enable);
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();
......@@ -247,15 +253,13 @@ public slots:
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 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(bool successful);
//void viewerClosed();
void dither();
void setSuspended(bool enable);
......@@ -263,6 +267,9 @@ public slots:
void setStatus(Ekos::GuideState newState);
// Star Position
void setStarPosition(const QVector3D &newCenter, bool updateNow);
// Capture
void setCaptureComplete();
......@@ -280,6 +287,8 @@ protected slots:
void setDefaultCCD(QString ccd);
void setDefaultST4(QString st4);
void updateTrackingBoxSize(int currentIndex);
signals:
void newLog();
void newStatus(Ekos::GuideState status);
......@@ -297,6 +306,7 @@ signals:
private:
void updateGuideParams();
void syncTrackingBoxPosition();
ISD::CCD *currentCCD;
ISD::Telescope *currentTelescope;
......@@ -310,20 +320,21 @@ private:
QTabWidget *tabWidget;
cgmath *pmath;
rcalibration *calibration;
rguider *guider;
internalCalibration *calibration;
internalGuider *guider;
PHD2 *phd2;
bool useGuideHead;
bool isSuspended;
bool phd2Connected;
QVector3D starCenter;
QStringList logText;
double ccd_hor_pixel, ccd_ver_pixel, focal_length, aperture, guideDeviationRA, guideDeviationDEC;
bool rapidGuideReticleSet;
GuideState state;
GuideState state;
};
}
......
......@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>616</width>
<height>317</height>
<width>669</width>
<height>55</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
......@@ -23,19 +23,6 @@
<item>
<widget class="QComboBox" name="guiderCombo"/>
</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="Line" name="line">
<property name="orientation">
......@@ -45,6 +32,9 @@
</item>
<item>
<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>
......@@ -53,19 +43,6 @@
<item>
<widget class="QComboBox" name="ST4Combo"/>
</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>
<item>
<widget class="Line" name="line_2">
<property name="orientation">
......@@ -75,8 +52,11 @@
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="toolTip">
<string>Exposure time in seconds</string>
</property>
<property name="text">
<string>Exposure:</string>
<string>Exp:</string>
</property>
</widget>
</item>
......@@ -90,19 +70,6 @@
</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>
<item>
<widget class="Line" name="line_3">
<property name="orientation">
......@@ -112,8 +79,11 @@
</item>
<item>
<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>Binning:</string>
<string>Bin:</string>
</property>
</widget>
</item>
......@@ -121,20 +91,53 @@
<widget class="QComboBox" name="binningCombo"/>
</item>
<item>
<spacer name="horizontalSpacer_5">
<widget class="Line" name="line_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</widget>
</item>
<item>
<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>
</spacer>
<property name="text">
<string>Box:</string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_4">
<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>
<widget class="Line" name="line_6">