diff --git a/kstars/ekos/guide/guide.h b/kstars/ekos/guide/guide.h
--- a/kstars/ekos/guide/guide.h
+++ b/kstars/ekos/guide/guide.h
@@ -10,6 +10,7 @@
#pragma once
#include "ui_guide.h"
+#include "guideinterface.h"
#include "ekos/ekos.h"
#include "indi/indiccd.h"
#include "indi/inditelescope.h"
@@ -27,7 +28,6 @@
namespace Ekos
{
-class GuideInterface;
class OpsCalibration;
class OpsGuide;
class InternalGuider;
@@ -401,6 +401,7 @@
void handleVerticalPlotSizeChange();
void handleHorizontalPlotSizeChange();
void clearGuideGraphs();
+ void clearCalibrationGraphs();
void slotAutoScaleGraphs();
void buildTarget();
void guideHistory();
@@ -457,6 +458,7 @@
void setAxisDelta(double ra, double de);
void setAxisSigma(double ra, double de);
void setAxisPulse(double ra, double de);
+ void calibrationUpdate(GuideInterface::CalibrationUpdateType type, const QString& message = QString(""), double dx = 0, double dy = 0);
void processGuideOptions();
@@ -535,6 +537,9 @@
// Init Functions
void initPlots();
+ void initDriftGraph();
+ void initDriftPlot();
+ void initCalibrationPlot();
void initView();
void initConnections();
@@ -644,5 +649,7 @@
//autostar is not selected, and the user has chosen a star.
//This connection storage is so that the connection can be disconnected after enforcement
QMetaObject::Connection guideConnect;
+
+ QCPItemText *calLabel { nullptr };
};
}
diff --git a/kstars/ekos/guide/guide.cpp b/kstars/ekos/guide/guide.cpp
--- a/kstars/ekos/guide/guide.cpp
+++ b/kstars/ekos/guide/guide.cpp
@@ -147,12 +147,16 @@
{
driftPlot->xAxis->setScaleRatio(driftPlot->yAxis, 1.0);
driftPlot->replot();
+ calibrationPlot->xAxis->setScaleRatio(calibrationPlot->yAxis, 1.0);
+ calibrationPlot->replot();
}
void Guide::handleVerticalPlotSizeChange()
{
driftPlot->yAxis->setScaleRatio(driftPlot->xAxis, 1.0);
driftPlot->replot();
+ calibrationPlot->yAxis->setScaleRatio(calibrationPlot->xAxis, 1.0);
+ calibrationPlot->replot();
}
void Guide::guideAfterMeridianFlip()
@@ -274,6 +278,15 @@
setupNSEWLabels();
}
+void Guide::clearCalibrationGraphs()
+{
+ calibrationPlot->graph(0)->data()->clear(); //RA out
+ calibrationPlot->graph(1)->data()->clear(); //RA back
+ calibrationPlot->graph(2)->data()->clear(); //DEC out
+ calibrationPlot->graph(3)->data()->clear(); //DEC back
+ calibrationPlot->replot();
+}
+
void Guide::setupNSEWLabels()
{
//Labels for N/S/E/W
@@ -362,6 +375,15 @@
driftPlot->xAxis->setScaleRatio(driftPlot->yAxis, 1.0);
driftPlot->replot();
+
+ calibrationPlot->xAxis->setRange(-10, 10);
+ calibrationPlot->yAxis->setRange(-10, 10);
+ calibrationPlot->graph(0)->rescaleAxes(true);
+
+ calibrationPlot->yAxis->setScaleRatio(calibrationPlot->xAxis, 1.0);
+ calibrationPlot->xAxis->setScaleRatio(calibrationPlot->yAxis, 1.0);
+
+ calibrationPlot->replot();
}
void Guide::guideHistory()
@@ -1808,6 +1830,7 @@
break;
case GUIDE_CALIBRATING:
+ clearCalibrationGraphs();
appendLogText(i18n("Calibration started."));
setBusy(true);
break;
@@ -2191,6 +2214,7 @@
connect(guider, &Ekos::GuideInterface::newAxisDelta, this, &Ekos::Guide::setAxisDelta);
connect(guider, &Ekos::GuideInterface::newAxisPulse, this, &Ekos::Guide::setAxisPulse);
connect(guider, &Ekos::GuideInterface::newAxisSigma, this, &Ekos::Guide::setAxisSigma);
+ connect(guider, &Ekos::GuideInterface::calibrationUpdate, this, &Ekos::Guide::calibrationUpdate);
connect(guider, &Ekos::GuideInterface::guideEquipmentUpdated, this, &Ekos::Guide::configurePHD2Camera);
}
@@ -2562,6 +2586,30 @@
emit newProfilePixmap(profilePixmap);
}
+void Guide::calibrationUpdate(GuideInterface::CalibrationUpdateType type, const QString& message,
+ double dx, double dy)
+{
+ switch (type)
+ {
+ case GuideInterface::RA_IN:
+ calibrationPlot->graph(0)->addData(dx, dy);
+ break;
+ case GuideInterface::RA_OUT:
+ calibrationPlot->graph(1)->addData(dx, dy);
+ break;
+ case GuideInterface::DEC_IN:
+ calibrationPlot->graph(2)->addData(dx, dy);
+ break;
+ case GuideInterface::DEC_OUT:
+ calibrationPlot->graph(3)->addData(dx, dy);
+ break;
+ case GuideInterface::CALIBRATION_MESSAGE_ONLY:
+ ;
+ }
+ calLabel->setText(message);
+ calibrationPlot->replot();
+}
+
void Guide::setAxisSigma(double ra, double de)
{
l_ErrRA->setText(QString::number(ra, 'f', 2));
@@ -3180,6 +3228,25 @@
}
void Guide::initPlots()
+{
+ initDriftGraph();
+ initDriftPlot();
+ initCalibrationPlot();
+
+ connect(rightLayout, &QSplitter::splitterMoved, this, &Ekos::Guide::handleVerticalPlotSizeChange);
+ connect(driftSplitter, &QSplitter::splitterMoved, this, &Ekos::Guide::handleHorizontalPlotSizeChange);
+
+ //This sets the values of all the Graph Options that are stored.
+ accuracyRadiusSpin->setValue(Options::guiderAccuracyThreshold());
+ showRAPlotCheck->setChecked(Options::rADisplayedOnGuideGraph());
+ showDECPlotCheck->setChecked(Options::dEDisplayedOnGuideGraph());
+ showRACorrectionsCheck->setChecked(Options::rACorrDisplayedOnGuideGraph());
+ showDECorrectionsCheck->setChecked(Options::dECorrDisplayedOnGuideGraph());
+
+ buildTarget();
+}
+
+void Guide::initDriftGraph()
{
// Drift Graph Color Settings
driftGraph->setBackground(QBrush(Qt::black));
@@ -3304,7 +3371,19 @@
connect(driftGraph, &QCustomPlot::mouseMove, this, &Ekos::Guide::driftMouseOverLine);
connect(driftGraph, &QCustomPlot::mousePress, this, &Ekos::Guide::driftMouseClicked);
+ //This sets the visibility of graph components to the stored values.
+ driftGraph->graph(0)->setVisible(Options::rADisplayedOnGuideGraph()); //RA data
+ driftGraph->graph(1)->setVisible(Options::dEDisplayedOnGuideGraph()); //DEC data
+ driftGraph->graph(2)->setVisible(Options::rADisplayedOnGuideGraph()); //RA highlighted point
+ driftGraph->graph(3)->setVisible(Options::dEDisplayedOnGuideGraph()); //DEC highlighted point
+ driftGraph->graph(4)->setVisible(Options::rACorrDisplayedOnGuideGraph()); //RA Pulses
+ driftGraph->graph(5)->setVisible(Options::dECorrDisplayedOnGuideGraph()); //DEC Pulses
+ updateCorrectionsScaleVisibility();
+}
+
+void Guide::initDriftPlot()
+{
//drift plot
double accuracyRadius = 2;
@@ -3358,29 +3437,85 @@
driftPlot->graph(1)->setLineStyle(QCPGraph::lsNone);
driftPlot->graph(1)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssPlusCircle, QPen(Qt::yellow, 2), QBrush(), 10));
- connect(rightLayout, &QSplitter::splitterMoved, this, &Ekos::Guide::handleVerticalPlotSizeChange);
- connect(driftSplitter, &QSplitter::splitterMoved, this, &Ekos::Guide::handleHorizontalPlotSizeChange);
+ driftPlot->resize(190, 190);
+ driftPlot->replot();
+}
- //This sets the values of all the Graph Options that are stored.
- accuracyRadiusSpin->setValue(Options::guiderAccuracyThreshold());
- showRAPlotCheck->setChecked(Options::rADisplayedOnGuideGraph());
- showDECPlotCheck->setChecked(Options::dEDisplayedOnGuideGraph());
- showRACorrectionsCheck->setChecked(Options::rACorrDisplayedOnGuideGraph());
- showDECorrectionsCheck->setChecked(Options::dECorrDisplayedOnGuideGraph());
+void Guide::initCalibrationPlot()
+{
+ calibrationPlot->setBackground(QBrush(Qt::black));
+ calibrationPlot->setSelectionTolerance(10);
- //This sets the visibility of graph components to the stored values.
- driftGraph->graph(0)->setVisible(Options::rADisplayedOnGuideGraph()); //RA data
- driftGraph->graph(1)->setVisible(Options::dEDisplayedOnGuideGraph()); //DEC data
- driftGraph->graph(2)->setVisible(Options::rADisplayedOnGuideGraph()); //RA highlighted point
- driftGraph->graph(3)->setVisible(Options::dEDisplayedOnGuideGraph()); //DEC highlighted point
- driftGraph->graph(4)->setVisible(Options::rACorrDisplayedOnGuideGraph()); //RA Pulses
- driftGraph->graph(5)->setVisible(Options::dECorrDisplayedOnGuideGraph()); //DEC Pulses
- updateCorrectionsScaleVisibility();
+ calibrationPlot->xAxis->setBasePen(QPen(Qt::white, 1));
+ calibrationPlot->yAxis->setBasePen(QPen(Qt::white, 1));
- driftPlot->resize(190, 190);
- driftPlot->replot();
+ calibrationPlot->xAxis->setTickPen(QPen(Qt::white, 1));
+ calibrationPlot->yAxis->setTickPen(QPen(Qt::white, 1));
- buildTarget();
+ calibrationPlot->xAxis->setSubTickPen(QPen(Qt::white, 1));
+ calibrationPlot->yAxis->setSubTickPen(QPen(Qt::white, 1));
+
+ calibrationPlot->xAxis->setTickLabelColor(Qt::white);
+ calibrationPlot->yAxis->setTickLabelColor(Qt::white);
+
+ calibrationPlot->xAxis->setLabelColor(Qt::white);
+ calibrationPlot->yAxis->setLabelColor(Qt::white);
+
+ calibrationPlot->xAxis->setLabelFont(QFont(font().family(), 10));
+ calibrationPlot->yAxis->setLabelFont(QFont(font().family(), 10));
+ calibrationPlot->xAxis->setTickLabelFont(QFont(font().family(), 9));
+ calibrationPlot->yAxis->setTickLabelFont(QFont(font().family(), 9));
+
+ calibrationPlot->xAxis->setLabelPadding(2);
+ calibrationPlot->yAxis->setLabelPadding(2);
+
+ calibrationPlot->xAxis->grid()->setPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine));
+ calibrationPlot->yAxis->grid()->setPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine));
+ calibrationPlot->xAxis->grid()->setSubGridPen(QPen(QColor(80, 80, 80), 1, Qt::DotLine));
+ calibrationPlot->yAxis->grid()->setSubGridPen(QPen(QColor(80, 80, 80), 1, Qt::DotLine));
+ calibrationPlot->xAxis->grid()->setZeroLinePen(QPen(Qt::gray));
+ calibrationPlot->yAxis->grid()->setZeroLinePen(QPen(Qt::gray));
+
+ calibrationPlot->xAxis->setLabel(i18n("x (pixels)"));
+ calibrationPlot->yAxis->setLabel(i18n("y (pixels)"));
+
+ calibrationPlot->xAxis->setRange(-10, 10);
+ calibrationPlot->yAxis->setRange(-10, 10);
+
+ calibrationPlot->setInteractions(QCP::iRangeZoom);
+ calibrationPlot->setInteraction(QCP::iRangeDrag, true);
+
+ calibrationPlot->addGraph();
+ calibrationPlot->graph(0)->setLineStyle(QCPGraph::lsNone);
+ calibrationPlot->graph(0)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDisc, QPen(KStarsData::Instance()->colorScheme()->colorNamed("RAGuideError"), 2), QBrush(), 6));
+ calibrationPlot->graph(0)->setName("RA out");
+
+ calibrationPlot->addGraph();
+ calibrationPlot->graph(1)->setLineStyle(QCPGraph::lsNone);
+ calibrationPlot->graph(1)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, QPen(Qt::white, 2), QBrush(), 4));
+ calibrationPlot->graph(1)->setName("RA in");
+
+ calibrationPlot->addGraph();
+ calibrationPlot->graph(2)->setLineStyle(QCPGraph::lsNone);
+ calibrationPlot->graph(2)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDisc, QPen(KStarsData::Instance()->colorScheme()->colorNamed("DEGuideError"), 2), QBrush(), 6));
+ calibrationPlot->graph(2)->setName("DEC out");
+
+ calibrationPlot->addGraph();
+ calibrationPlot->graph(3)->setLineStyle(QCPGraph::lsNone);
+ calibrationPlot->graph(3)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, QPen(Qt::yellow, 2), QBrush(), 4));
+ calibrationPlot->graph(3)->setName("DEC in");
+
+ calLabel = new QCPItemText(calibrationPlot);
+ calLabel->setColor(QColor(255,255,255));
+ calLabel->setPositionAlignment(Qt::AlignTop|Qt::AlignHCenter);
+ calLabel->position->setType(QCPItemPosition::ptAxisRectRatio);
+ calLabel->position->setCoords(0.5, 0);
+ calLabel->setText("");
+ calLabel->setFont(QFont(font().family(), 10));
+ calLabel->setVisible(true);
+
+ calibrationPlot->resize(190, 190);
+ calibrationPlot->replot();
}
void Guide::initView()
diff --git a/kstars/ekos/guide/guide.ui b/kstars/ekos/guide/guide.ui
--- a/kstars/ekos/guide/guide.ui
+++ b/kstars/ekos/guide/guide.ui
@@ -1146,7 +1146,7 @@
- Control parameters
+ Control
@@ -1425,6 +1425,41 @@
+
+
+ Calibration Plot
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 200
+ 200
+
+
+
+
+
+
diff --git a/kstars/ekos/guide/guideinterface.h b/kstars/ekos/guide/guideinterface.h
--- a/kstars/ekos/guide/guideinterface.h
+++ b/kstars/ekos/guide/guideinterface.h
@@ -58,15 +58,24 @@
virtual void setStarPosition(QVector3D& starCenter);
+ enum CalibrationUpdateType
+ {
+ RA_IN,
+ RA_OUT,
+ DEC_IN,
+ DEC_OUT,
+ CALIBRATION_MESSAGE_ONLY
+ };
+
signals:
void newLog(const QString &);
void newStatus(Ekos::GuideState);
void newAxisDelta(double delta_ra, double delta_dec);
void newAxisSigma(double sigma_ra, double sigma_dec);
void newAxisPulse(double pulse_ra, double pulse_dec);
void newStarPosition(const QVector3D &newCenter, bool updateNow);
void newStarPixmap(QPixmap &);
-
+ void calibrationUpdate(CalibrationUpdateType type, const QString &message = QString(""), double x = 0, double y = 0);
void frameCaptureRequested();
void guideEquipmentUpdated();
diff --git a/kstars/ekos/guide/internalguide/internalguider.cpp b/kstars/ekos/guide/internalguide/internalguider.cpp
--- a/kstars/ekos/guide/internalguide/internalguider.cpp
+++ b/kstars/ekos/guide/internalguide/internalguider.cpp
@@ -425,7 +425,7 @@
calibrationStage = CAL_ERROR;
emit newStatus(Ekos::GUIDE_CALIBRATION_ERROR);
-
+ emit calibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY, i18n("Calibration Failed: Lost guide star."));
return;
}
@@ -489,6 +489,7 @@
m_CalibrationParams.last_pulse = Options::calibrationPulseDuration();
+ emit calibrationUpdate(GuideInterface::RA_IN, i18n("Guide Star found."), 0, 0);
qCDebug(KSTARS_EKOS_GUIDE) << "Auto Iteration #" << m_CalibrationParams.auto_drift_time << "Default pulse:" <<
m_CalibrationParams.last_pulse;
qCDebug(KSTARS_EKOS_GUIDE) << "Start X1 " << m_CalibrationCoords.start_x1 << " Start Y1 " << m_CalibrationCoords.start_y1;
@@ -512,6 +513,9 @@
double cur_x, cur_y;
pmath->getStarScreenPosition(&cur_x, &cur_y);
+ emit calibrationUpdate(GuideInterface::RA_IN, i18n("Calibrating RA Out"),
+ cur_x - m_CalibrationCoords.start_x1, cur_y - m_CalibrationCoords.start_y1);
+
qCDebug(KSTARS_EKOS_GUIDE) << "Iteration #" << m_CalibrationParams.ra_iterations << ": STAR " << cur_x << "," << cur_y;
qCDebug(KSTARS_EKOS_GUIDE) << "Iteration " << m_CalibrationParams.ra_iterations << " Direction: RA_INC_DIR" << " Duration: "
<< m_CalibrationParams.last_pulse << " ms.";
@@ -551,7 +555,7 @@
calibrationStage = CAL_ERROR;
emit newStatus(Ekos::GUIDE_CALIBRATION_ERROR);
-
+ emit calibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY, i18n("Calibration Failed: Drift too short."));
KSNotification::event(QLatin1String("CalibrationFailed"), i18n("Guiding calibration failed with errors"),
KSNotification::EVENT_ALERT);
@@ -587,6 +591,8 @@
double cur_x, cur_y;
pmath->getStarScreenPosition(&cur_x, &cur_y);
+ emit calibrationUpdate(GuideInterface::RA_OUT, i18n("Calibrating RA In"),
+ cur_x - m_CalibrationCoords.start_x1, cur_y - m_CalibrationCoords.start_y1);
qCDebug(KSTARS_EKOS_GUIDE) << "Iteration #" << m_CalibrationParams.ra_iterations << ": STAR " << cur_x << "," << cur_y;
qCDebug(KSTARS_EKOS_GUIDE) << "Iteration " << m_CalibrationParams.ra_iterations << " Direction: RA_DEC_DIR" << " Duration: "
<< m_CalibrationParams.last_pulse << " ms.";
@@ -645,7 +651,7 @@
calibrationStage = CAL_ERROR;
emit newStatus(Ekos::GUIDE_CALIBRATION_ERROR);
-
+ emit calibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY, i18n("Calibration Failed: couldn't reach start."));
emit newLog(i18np("Guide RA: Scope cannot reach the start point after %1 iteration. Possible mount or "
"backlash problems...",
"GUIDE_RA: Scope cannot reach the start point after %1 iterations. Possible mount or "
@@ -694,7 +700,7 @@
calibrationStage = CAL_ERROR;
emit newStatus(Ekos::GUIDE_CALIBRATION_ERROR);
-
+ emit calibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY, i18n("Calibration Failed: drift too short."));
KSNotification::event(QLatin1String("CalibrationFailed"),
i18n("Guiding calibration failed with errors"), KSNotification::EVENT_ALERT);
}
@@ -709,6 +715,9 @@
double cur_x, cur_y;
pmath->getStarScreenPosition(&cur_x, &cur_y);
+ emit calibrationUpdate(GuideInterface::DEC_IN, i18n("Calibrating DEC Out"),
+ cur_x - m_CalibrationCoords.start_x2, cur_y - m_CalibrationCoords.start_y2);
+
qCDebug(KSTARS_EKOS_GUIDE) << "Iteration #" << m_CalibrationParams.dec_iterations << ": STAR " << cur_x << "," << cur_y;
qCDebug(KSTARS_EKOS_GUIDE) << "Iteration " << m_CalibrationParams.dec_iterations << " Direction: DEC_INC_DIR" <<
" Duration: " << m_CalibrationParams.last_pulse << " ms.";
@@ -745,7 +754,7 @@
calibrationStage = CAL_ERROR;
emit newStatus(Ekos::GUIDE_CALIBRATION_ERROR);
-
+ emit calibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY, i18n("Calibration Failed: couldn't reach start point."));
emit newLog(i18np("Guide DEC: Scope cannot reach the start point after %1 iteration.\nPossible mount "
"or backlash problems...",
"GUIDE DEC: Scope cannot reach the start point after %1 iterations.\nPossible mount "
@@ -784,6 +793,9 @@
double cur_x, cur_y;
pmath->getStarScreenPosition(&cur_x, &cur_y);
+ emit calibrationUpdate(GuideInterface::DEC_OUT, i18n("Calibrating DEC In"),
+ cur_x - m_CalibrationCoords.start_x2, cur_y - m_CalibrationCoords.start_y2);
+
// Star position resulting from LAST guiding pulse to mount
qCDebug(KSTARS_EKOS_GUIDE) << "Iteration #" << m_CalibrationParams.dec_iterations << ": STAR " << cur_x << "," << cur_y;
qCDebug(KSTARS_EKOS_GUIDE) << "Iteration " << m_CalibrationParams.dec_iterations << " Direction: DEC_DEC_DIR" <<
@@ -833,6 +845,7 @@
calibrationStage = CAL_ERROR;
emit newStatus(Ekos::GUIDE_CALIBRATION_ERROR);
+ emit calibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY, i18n("Calibration Failed: couldn't reach start point."));
emit newLog(i18np("Guide DEC: Scope cannot reach the start point after %1 iteration.\nPossible mount "
"or backlash problems...",
@@ -864,6 +877,7 @@
emit DESwapChanged(swap_dec);
+ emit calibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY, i18n("Calibration Successful"));
KSNotification::event(QLatin1String("CalibrationSuccessful"),
i18n("Guiding calibration completed successfully"));
@@ -873,6 +887,7 @@
else
{
emit newLog(i18n("Calibration rejected. Star drift is too short. Check for mount, cable, or backlash problems."));
+ emit calibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY, i18n("Calibration Failed: drift too short."));
emit newStatus(Ekos::GUIDE_CALIBRATION_ERROR);