9#include "guideadaptor.h"
11#include "ksmessagebox.h"
12#include "kstarsdata.h"
13#include "opscalibration.h"
18#include "indi/indiguider.h"
19#include "indi/indiadaptiveoptics.h"
20#include "auxiliary/QProgressIndicator.h"
21#include "ekos/auxiliary/opticaltrainmanager.h"
22#include "ekos/auxiliary/profilesettings.h"
23#include "ekos/auxiliary/opticaltrainsettings.h"
24#include "ekos/auxiliary/darklibrary.h"
25#include "externalguide/linguider.h"
26#include "externalguide/phd2.h"
27#include "fitsviewer/fitsdata.h"
28#include "fitsviewer/fitsview.h"
29#include "fitsviewer/fitsviewer.h"
30#include "internalguide/internalguider.h"
32#include "guidegraph.h"
33#include "guidestatewidget.h"
34#include "manualpulse.h"
35#include "ekos/auxiliary/darkprocessor.h"
37#include <KConfigDialog>
39#include <basedevice.h>
40#include <ekos_guide_debug.h>
42#include "ui_manualdither.h"
46#define CAPTURE_TIMEOUT_THRESHOLD 30000
53 internalGuider =
new InternalGuider();
57 opsGuide =
new OpsGuide();
60 connect(opsGuide, &OpsGuide::settingsUpdated,
this, [
this]()
62 onThresholdChanged(Options::guideAlgorithm());
63 configurePHD2Camera();
64 configSEPMultistarOptions();
68 opsCalibration =
new OpsCalibration(internalGuider);
69 page = dialog->
addPage(opsCalibration,
i18n(
"Calibration"));
72 opsDither =
new OpsDither();
76 opsGPG =
new OpsGPG(internalGuider);
77 page = dialog->
addPage(opsGPG,
i18n(
"GPG RA Guider"));
94 internalGuider->setGuideView(m_GuideView);
145 exposureValues << 0.02 << 0.05 << 0.1 << 0.2 << 0.5 << 1 << 1.5 << 2 << 2.5 << 3 << 3.5 << 4 << 4.5 << 5 << 6 << 7 << 8 << 9
154 if(guiderType == GUIDE_PHD2)
156 setExternalGuiderBLOBEnabled(!Options::guideSubframe());
161 opsDither->kcfg_DitherTimeout->setEnabled(
false);
162 opsDither->kcfg_DitherThreshold->setEnabled(
false);
163 opsDither->kcfg_DitherMaxIterations->setEnabled(!Options::ditherWithOnePulse());
167 resetNonGuidedDither();
173 button->setAutoDefault(
false);
177 m_DarkProcessor =
new DarkProcessor(
this);
178 connect(m_DarkProcessor, &DarkProcessor::newLog,
this, &Ekos::Guide::appendLogText);
179 connect(m_DarkProcessor, &DarkProcessor::darkFrameCompleted,
this, [
this](
bool completed)
182 setDarkFrameEnabled(completed);
183 m_GuideView->setProperty(
"suspended",
false);
186 m_GuideView->rescale(ZOOM_KEEP_LEVEL);
187 m_GuideView->updateFrame();
189 m_GuideView->updateFrame();
190 setCaptureComplete();
193 m_ManaulPulse =
new ManualPulse(
this);
194 connect(m_ManaulPulse, &ManualPulse::newSinglePulse,
this, &Guide::sendSinglePulse);
197 m_ManaulPulse->reset();
198 m_ManaulPulse->show();
201 loadGlobalSettings();
204 setupOpticalTrainManager();
209 delete m_GuiderInstance;
212void Guide::handleHorizontalPlotSizeChange()
219void Guide::handleVerticalPlotSizeChange()
226void Guide::guideAfterMeridianFlip()
230 m_GuideView->setTrackingBoxEnabled(
false);
233 if (Options::resetGuideCalibration())
237 if (Options::gPGEnabled())
238 m_GuiderInstance->resetGPG();
245 if (
event->oldSize().width() != -1)
247 if (
event->oldSize().width() != size().width())
248 handleHorizontalPlotSizeChange();
249 else if (
event->oldSize().height() != size().height())
250 handleVerticalPlotSizeChange();
258void Guide::buildTarget()
263void Guide::clearGuideGraphs()
269void Guide::clearCalibrationGraphs()
279void Guide::slotAutoScaleGraphs()
292void Guide::guideHistory()
296 double ra =
driftGraph->graph(GuideGraph::G_RA)->dataMainValue(sliderValue);
297 double de =
driftGraph->graph(GuideGraph::G_DEC)->dataMainValue(sliderValue);
298 driftGraph->guideHistory(sliderValue, graphOnLatestPt);
303void Guide::setLatestGuidePoint(
bool isChecked)
305 graphOnLatestPt = isChecked;
321 if (m_Camera && device == m_Camera)
328 m_Camera->disconnect(
this);
334 connect(m_Camera, &ISD::Camera::Connected,
this, [
this]()
338 connect(m_Camera, &ISD::ConcreteDevice::Disconnected,
this, [
this]()
350 if(guiderType != GUIDE_INTERNAL)
351 m_Camera->setBLOBEnabled(
false);
354 configurePHD2Camera();
357 if (captureTimeout.isActive() && m_State >= Ekos::GUIDE_CAPTURE)
363void Guide::configurePHD2Camera()
367 if(guiderType != GUIDE_PHD2)
374 if(!phd2Guider->isConnected())
378 if(phd2Guider->getCurrentCamera().isEmpty())
380 phd2Guider->requestCurrentEquipmentUpdate();
387 if(m_Camera && phd2Guider->getCurrentCamera().contains(m_Camera->getDeviceName()))
404 setExternalGuiderBLOBEnabled(
false);
412 m_LastPHD2MountName = phd2Guider->getCurrentMount();
415 phd2Guider->setCurrentCameraIsNotInEkos(m_Camera ==
nullptr);
417 if(phd2Guider->isCurrentCameraNotInEkos())
420 i18n(
"PHD2's current camera: %1, is not connected to Ekos. The PHD2 Guide Star Image will be received, but the full external guide frames cannot.",
421 phd2Guider->getCurrentCamera()));
430 i18n(
"PHD2's current camera: %1, is connected to Ekos. You can select whether to use the full external guide frames or just receive the PHD2 Guide Star Image using the SubFrame checkbox.",
431 phd2Guider->getCurrentCamera()));
439 if (m_Mount && m_Mount == device)
446 m_Mount->disconnect(
this);
456 return m_Camera->getDeviceName();
461void Guide::checkCamera()
465 if (!m_Camera || guiderType != GUIDE_INTERNAL)
473 case GUIDE_CONNECTED:
474 case GUIDE_DISCONNECTED:
475 case GUIDE_CALIBRATION_ERROR:
483 case GUIDE_STAR_SELECT:
484 case GUIDE_CALIBRATING:
485 case GUIDE_CALIBRATION_SUCCESS:
487 case GUIDE_SUSPENDED:
488 case GUIDE_REACQUIRE:
489 case GUIDE_DITHERING:
490 case GUIDE_MANUAL_DITHERING:
491 case GUIDE_DITHERING_ERROR:
492 case GUIDE_DITHERING_SUCCESS:
493 case GUIDE_DITHERING_SETTLE:
499 auto targetChip = m_Camera->getChip(useGuideHead ? ISD::CameraChip::GUIDE_CCD : ISD::CameraChip::PRIMARY_CCD);
502 qCCritical(
KSTARS_EKOS_GUIDE) <<
"Failed to retrieve active guide chip in camera";
506 if (targetChip->isCapturing())
509 if (guiderType != GUIDE_INTERNAL)
521void Ekos::Guide::checkUseGuideHead()
523 if (m_Camera ==
nullptr)
526 if (m_Camera->hasGuideHead() && Options::useGuideHead())
529 useGuideHead =
false;
531 opsGuide->kcfg_UseGuideHead->
setEnabled(m_Camera->hasGuideHead());
534void Guide::syncCameraInfo()
539 auto nvp = m_Camera->getNumber(useGuideHead ?
"GUIDER_INFO" :
"CCD_INFO");
543 auto np =
nvp->findWidgetByName(
"CCD_PIXEL_SIZE_X");
545 ccdPixelSizeX = np->getValue();
547 np =
nvp->findWidgetByName(
"CCD_PIXEL_SIZE_Y");
549 ccdPixelSizeY = np->getValue();
551 np =
nvp->findWidgetByName(
"CCD_PIXEL_SIZE_Y");
553 ccdPixelSizeY = np->getValue();
559void Guide::syncTelescopeInfo()
561 if (m_Mount ==
nullptr || m_Mount->isConnected() ==
false)
567void Guide::updateGuideParams()
569 if (m_Camera ==
nullptr)
574 ISD::CameraChip *targetChip = m_Camera->getChip(useGuideHead ? ISD::CameraChip::GUIDE_CCD :
ISD::CameraChip::PRIMARY_CCD);
576 if (targetChip ==
nullptr)
578 appendLogText(
i18n(
"Connection to the guide CCD is lost."));
582 if (targetChip->getFrameType() != FRAME_LIGHT)
585 if(guiderType == GUIDE_INTERNAL)
588 int subBinX = 1, subBinY = 1;
589 if (targetChip->canBin())
593 targetChip->getBinning(&subBinX, &subBinY);
597 if( guideBinIndex >= 0 && guideBinIndex <
maxBinX && guideBinIndex <
maxBinY )
599 subBinX = guideBinIndex + 1;
600 subBinY = guideBinIndex + 1;
603 guideBinIndex = subBinX - 1;
608 for (
int i = 1; i <=
maxBinX; i++)
617 if (frameSettings.
contains(targetChip) ==
false)
620 if (targetChip->getFrame(&
x, &
y, &w, &h))
628 QVariantMap settings;
634 settings[
"binx"] = subBinX;
635 settings[
"biny"] = subBinY;
637 frameSettings[targetChip] = settings;
644 QVariantMap settings = frameSettings[targetChip];
645 settings[
"binx"] = subBinX;
646 settings[
"biny"] = subBinY;
647 frameSettings[targetChip] = settings;
650 if (ccdPixelSizeX != -1 && ccdPixelSizeY != -1 && m_FocalLength > 0)
653 m_GuiderInstance->setGuiderParams(ccdPixelSizeX, ccdPixelSizeY, m_Aperture,
effectiveFocaLength);
654 emit guideChipUpdated(targetChip);
657 if (targetChip->getFrame(&
x, &
y, &w, &h))
659 m_GuiderInstance->setFrameParams(
x,
y, w, h, subBinX, subBinY);
670 if (m_FocalRatio > 0)
671 l_FbyD->setText(
QString(
"F/%1").arg(m_FocalRatio, 0,
'f', 1));
672 else if (m_Aperture > 0)
673 l_FbyD->setText(
QString(
"F/%1").arg(m_FocalLength / m_Aperture, 0,
'f', 1));
680 double fov_w = (w * pixScaleX) / 60.0;
681 double fov_h = (h * pixScaleY) / 60.0;
689 if (guiderType != GUIDE_INTERNAL || (m_Guider && device == m_Guider))
699 connect(m_Guider, &ISD::ConcreteDevice::Connected,
this, [
this]()
703 connect(m_Guider, &ISD::ConcreteDevice::Disconnected,
this, [
this]()
705 guideB->setEnabled(
false);
709 guideB->setEnabled(m_Guider && m_Guider->isConnected());
715 if (guiderType != GUIDE_INTERNAL || (m_AO && device == m_AO))
728 if (guiderType != GUIDE_INTERNAL || m_Guider ==
nullptr)
731 return m_Guider->getDeviceName();
736 buildOperationStack(GUIDE_CAPTURE);
738 return executeOperationStack();
741bool Guide::captureOneFrame()
743 captureTimeout.
stop();
745 if (m_Camera ==
nullptr)
748 if (m_Camera->isConnected() ==
false)
750 appendLogText(
i18n(
"Error: lost connection to CCD."));
756 ISD::CameraChip *targetChip = m_Camera->getChip(useGuideHead ? ISD::CameraChip::GUIDE_CCD :
ISD::CameraChip::PRIMARY_CCD);
758 prepareCapture(targetChip);
764 if (frameSettings.
contains(targetChip))
766 QVariantMap settings = frameSettings[targetChip];
767 targetChip->setFrame(settings[
"x"].toInt(), settings[
"y"].toInt(), settings[
"w"].toInt(),
768 settings[
"h"].toInt());
769 targetChip->setBinning(settings[
"binx"].toInt(), settings[
"biny"].toInt());
779 if (operationStack.contains(GUIDE_STAR_SELECT) &&
guideAutoStar->isChecked() &&
780 !((guiderType == GUIDE_INTERNAL) && internalGuider->SEPMultiStarEnabled()))
784 m_GuideView->setProperty(
"suspended", operationStack.contains(GUIDE_DARK));
796 targetChip->setBatchMode(
false);
797 targetChip->setCaptureMode(FITS_GUIDE);
798 targetChip->setFrameType(FRAME_LIGHT);
799 targetChip->setCaptureFilter(FITS_NONE);
800 m_Camera->setEncodingFormat(
"FITS");
803void Guide::abortExposure()
805 if (m_Camera && guiderType == GUIDE_INTERNAL)
807 captureTimeout.
stop();
810 m_Camera->getChip(useGuideHead ? ISD::CameraChip::GUIDE_CCD :
ISD::CameraChip::PRIMARY_CCD);
811 if (targetChip->isCapturing())
814 targetChip->abortExposure();
821 if (m_Camera && guiderType == GUIDE_INTERNAL)
823 captureTimeout.
stop();
826 m_Camera->getChip(useGuideHead ? ISD::CameraChip::GUIDE_CCD : ISD::CameraChip::PRIMARY_CCD);
827 if (targetChip->isCapturing())
828 targetChip->abortExposure();
838 case GUIDE_CONNECTED:
839 case GUIDE_DISCONNECTED:
842 case GUIDE_CALIBRATING:
843 case GUIDE_DITHERING:
844 case GUIDE_STAR_SELECT:
848 m_GuiderInstance->abort();
858void Guide::setBusy(
bool enable)
862 else if (enable ==
false && pi->
isAnimated() ==
false)
868 guideB->setEnabled(
false);
870 loopB->setEnabled(
false);
874 stopB->setEnabled(
true);
877 trainB->setEnabled(
false);
883 if(guiderType != GUIDE_LINGUIDER)
886 loopB->setEnabled(
true);
887 guideAutoStar->setEnabled(!internalGuider->SEPMultiStarEnabled());
889 guideSubframe->setEnabled(!internalGuider->SEPMultiStarEnabled());
891 if (guiderType == GUIDE_INTERNAL)
894 if (calibrationComplete ||
895 ((guiderType == GUIDE_INTERNAL) &&
896 Options::reuseGuideCalibration() &&
897 !Options::serializedCalibration().isEmpty()))
900 stopB->setEnabled(
false);
911void Guide::processCaptureTimeout()
915 appendLogText(
i18n(
"Exposure timeout. Restarting exposure..."));
916 m_Camera->setEncodingFormat(
"FITS");
917 ISD::CameraChip *targetChip = m_Camera->getChip(useGuideHead ? ISD::CameraChip::GUIDE_CCD :
ISD::CameraChip::PRIMARY_CCD);
918 targetChip->abortExposure();
919 prepareCapture(targetChip);
927 m_CaptureTimeoutCounter++;
929 if (m_Camera ==
nullptr)
932 if (m_DeviceRestartCounter >= 3)
934 m_CaptureTimeoutCounter = 0;
935 m_DeviceRestartCounter = 0;
936 if (m_State == GUIDE_GUIDING)
937 appendLogText(
i18n(
"Exposure timeout. Aborting Autoguide."));
938 else if (m_State == GUIDE_DITHERING)
939 appendLogText(
i18n(
"Exposure timeout. Aborting Dithering."));
940 else if (m_State == GUIDE_CALIBRATING)
941 appendLogText(
i18n(
"Exposure timeout. Aborting Calibration."));
943 captureTimeout.
stop();
948 if (m_CaptureTimeoutCounter > 1)
950 QString camera = m_Camera->getDeviceName();
951 QString via = m_Guider ? m_Guider->getDeviceName() :
"";
952 ISD::CameraChip *targetChip = m_Camera->getChip(useGuideHead ? ISD::CameraChip::GUIDE_CCD :
ISD::CameraChip::PRIMARY_CCD);
953 QVariantMap settings = frameSettings[targetChip];
954 emit driverTimedout(camera);
957 m_DeviceRestartCounter++;
958 reconnectDriver(camera, settings);
966void Guide::reconnectDriver(
const QString &camera, QVariantMap settings)
968 if (m_Camera && m_Camera->getDeviceName() == camera)
971 Ekos::GuideState currentState = m_State;
972 m_State = GUIDE_IDLE;
975 m_State = currentState;
977 if (guiderType == GUIDE_INTERNAL)
980 ISD::CameraChip *targetChip = m_Camera->getChip(useGuideHead ? ISD::CameraChip::GUIDE_CCD :
ISD::CameraChip::PRIMARY_CCD);
981 frameSettings[targetChip] = settings;
983 m_CaptureTimeoutCounter = 0;
992 reconnectDriver(camera, settings);
998 ISD::CameraChip *targetChip = m_Camera->getChip(useGuideHead ? ISD::CameraChip::GUIDE_CCD : ISD::CameraChip::PRIMARY_CCD);
999 if (targetChip->getCaptureMode() != FITS_GUIDE)
1004 .
arg(data->property(
"blobVector").toString())
1005 .
arg(data->property(
"blobElement").toString())
1006 .
arg(data->property(
"chip").
toInt());
1009 targetChip->getCaptureMode();
1017 m_GuideView->loadData(data);
1021 m_ImageData.
reset();
1023 if (guiderType == GUIDE_INTERNAL)
1024 internalGuider->setImageData(m_ImageData);
1026 captureTimeout.
stop();
1027 m_CaptureTimeoutCounter = 0;
1033 int subBinX = 1, subBinY = 1;
1034 targetChip->getBinning(&subBinX, &subBinY);
1036 if (starCenter.
x() == 0 && starCenter.
y() == 0)
1038 int x = 0,
y = 0, w = 0, h = 0;
1040 if (frameSettings.
contains(targetChip))
1042 QVariantMap settings = frameSettings[targetChip];
1043 x = settings[
"x"].toInt();
1044 y = settings[
"y"].toInt();
1045 w = settings[
"w"].toInt();
1046 h = settings[
"h"].toInt();
1049 targetChip->getFrame(&
x, &
y, &w, &h);
1051 starCenter.
setX(w / (2 * subBinX));
1052 starCenter.
setY(h / (2 * subBinY));
1053 starCenter.
setZ(subBinX);
1056 syncTrackingBoxPosition();
1059 setCaptureComplete();
1064void Guide::setCaptureComplete()
1066 if (!m_GuideView.
isNull())
1067 m_GuideView->clearNeighbors();
1069 DarkLibrary::Instance()->disconnect(
this);
1071 if (operationStack.isEmpty() ==
false)
1073 executeOperationStack();
1077 qCDebug(
KSTARS_EKOS_GUIDE) <<
"Capture complete, state=" << getGuideStatusString(m_State);
1082 case GUIDE_CONNECTED:
1083 case GUIDE_DISCONNECTED:
1084 case GUIDE_CALIBRATION_SUCCESS:
1085 case GUIDE_CALIBRATION_ERROR:
1086 case GUIDE_DITHERING_ERROR:
1092 m_State = GUIDE_IDLE;
1093 emit newStatus(m_State);
1101 case GUIDE_CALIBRATING:
1102 m_GuiderInstance->calibrate();
1106 m_GuiderInstance->guide();
1109 case GUIDE_DITHERING:
1110 m_GuiderInstance->dither(Options::ditherPixels());
1114 case GUIDE_MANUAL_DITHERING:
1115 dynamic_cast<InternalGuider*
>(m_GuiderInstance)->processManualDithering();
1118 case GUIDE_REACQUIRE:
1119 m_GuiderInstance->reacquire();
1122 case GUIDE_DITHERING_SETTLE:
1123 if (Options::ditherNoGuiding())
1128 case GUIDE_SUSPENDED:
1129 if (Options::gPGEnabled())
1130 m_GuiderInstance->guide();
1137 emit newImage(m_GuideView);
1138 emit newStarPixmap(m_GuideView->getTrackingBoxPixmap(10));
1141void Guide::appendLogText(
const QString &text)
1143 m_LogText.
insert(0,
i18nc(
"log entry; %1 is the date, %2 is the text",
"%1 %2",
1144 KStarsData::Instance()->lt().
toString(
"yyyy-MM-ddThh:mm:ss"), text));
1159 if (m_Guider ==
nullptr || m_GuiderInstance ==
nullptr)
1162 if (guiderType == GUIDE_INTERNAL)
1164 dynamic_cast<InternalGuider *
>(m_GuiderInstance)->
setDECSwap(enable);
1165 m_Guider->setDECSwap(enable);
1172 if (m_Guider ==
nullptr || (
ra_dir == NO_DIR &&
dec_dir == NO_DIR))
1180 auto delay = std::max(
static_cast<int>(
guideDelay->value() * 1000),
ms);
1182 m_PulseTimer.
start(delay);
1189 if (m_Guider ==
nullptr || dir == NO_DIR)
1197 auto delay = std::max(
static_cast<int>(
guideDelay->value() * 1000),
ms);
1199 m_PulseTimer.
start(delay);
1202 return m_Guider->doPulse(dir,
msecs);
1208 m_State = GUIDE_IDLE;
1210 emit newStatus(m_State);
1212 if (guiderType == GUIDE_INTERNAL)
1220 auto targetChip = m_Camera->getChip(useGuideHead ? ISD::CameraChip::GUIDE_CCD : ISD::CameraChip::PRIMARY_CCD);
1222 if (frameSettings.
contains(targetChip))
1224 targetChip->resetFrame();
1226 targetChip->getFrame(&
x, &
y, &w, &h);
1227 QVariantMap settings = frameSettings[targetChip];
1232 frameSettings[targetChip] = settings;
1238 buildOperationStack(GUIDE_CALIBRATING);
1240 executeOperationStack();
1242 if (m_Camera && m_Guider)
1244 qCDebug(
KSTARS_EKOS_GUIDE) <<
"Starting calibration using camera:" << m_Camera->getDeviceName() <<
"via" <<
1245 m_Guider->getDeviceName();
1255 if(guiderType != GUIDE_PHD2)
1257 if (calibrationComplete ==
false)
1264 m_GuiderInstance->guide();
1272 if(guiderType == GUIDE_PHD2 && m_GuideView->isTrackingBoxEnabled())
1274 double x = starCenter.
x();
1275 double y = starCenter.
y();
1277 if(!m_ImageData.
isNull())
1279 if(m_ImageData->width() > 50)
1281 guideConnect =
connect(
this, &Guide::newStatus,
this, [
this,
x,
y](Ekos::GuideState
newState)
1285 phd2Guider->setLockPosition(
x,
y);
1295 if (m_MountStatus == ISD::Mount::MOUNT_PARKED)
1297 KSMessageBox::Instance()->sorry(
i18n(
"The mount is parked. Unpark to start guiding."));
1307 if (Options::ditherNoGuiding() && m_State == GUIDE_IDLE)
1313 if (m_State == GUIDE_DITHERING || m_State == GUIDE_DITHERING_SETTLE)
1317 double time = guideTimer.
elapsed() / 1000.0;
1328 if (guiderType == GUIDE_INTERNAL && !Options::ditherWithOnePulse())
1330 if (m_State != GUIDE_GUIDING)
1333 setStatus(GUIDE_DITHERING);
1338 return m_GuiderInstance->dither(Options::ditherPixels());
1343 if (m_State == GUIDE_SUSPENDED)
1345 else if (m_State >= GUIDE_CAPTURE)
1346 return m_GuiderInstance->suspend();
1353 if (m_State == GUIDE_GUIDING)
1355 else if (m_State == GUIDE_SUSPENDED)
1356 return m_GuiderInstance->resume();
1375 resetNonGuidedDither();
1382void Guide::setPierSide(ISD::Mount::PierSide
newSide)
1384 m_GuiderInstance->setPierSide(
newSide);
1389 if (guiderType == GUIDE_INTERNAL &&
1390 m_State != GUIDE_GUIDING &&
1391 m_State != GUIDE_CALIBRATING &&
1392 calibrationComplete)
1395 if (Options::reuseGuideCalibration())
1396 calibrationComplete =
false;
1400 appendLogText(
i18n(
"Pier side change detected. Clearing calibration."));
1405void Guide::setMountStatus(ISD::Mount::Status
newState)
1409 if (
newState == ISD::Mount::MOUNT_PARKING ||
newState == ISD::Mount::MOUNT_SLEWING)
1412 if (Options::resetGuideCalibration())
1414 appendLogText(
i18n(
"Mount is moving. Resetting calibration..."));
1417 else if (Options::reuseGuideCalibration() && (guiderType == GUIDE_INTERNAL))
1420 calibrationComplete =
false;
1423 if (Options::gPGEnabled())
1424 m_GuiderInstance->resetGPG();
1427 if (m_State == GUIDE_GUIDING || m_State == GUIDE_DITHERING)
1429 if (
newState == ISD::Mount::MOUNT_PARKING)
1430 appendLogText(
i18n(
"Mount is parking. Aborting guide..."));
1432 appendLogText(
i18n(
"Mount is slewing. Aborting guide..."));
1438 if (guiderType != GUIDE_INTERNAL)
1443 case ISD::Mount::MOUNT_SLEWING:
1444 case ISD::Mount::MOUNT_PARKING:
1445 case ISD::Mount::MOUNT_MOVING:
1447 loopB->setEnabled(
false);
1456 loopB->setEnabled(
true);
1463void Guide::setMountCoords(
const SkyPoint &position, ISD::Mount::PierSide pierSide,
const dms &ha)
1466 m_GuiderInstance->setMountCoords(position, pierSide);
1467 m_ManaulPulse->setMountCoords(position);
1479 if(guiderType == GUIDE_PHD2)
1480 setExternalGuiderBLOBEnabled(!enable);
1485 if(guiderType == GUIDE_INTERNAL)
1491 calibrationComplete =
false;
1493 m_GuiderInstance->clearCalibration();
1495 appendLogText(
i18n(
"Calibration is cleared."));
1498void Guide::setStatus(Ekos::GuideState
newState)
1504 emit newStatus(m_State);
1511 emit newStatus(m_State);
1515 case GUIDE_CONNECTED:
1516 appendLogText(
i18n(
"External guider connected."));
1520 guideB->setEnabled(
true);
1522 if(guiderType == GUIDE_PHD2)
1525 loopB->setEnabled(
true);
1527 configurePHD2Camera();
1533 case GUIDE_DISCONNECTED:
1534 appendLogText(
i18n(
"External guider disconnected."));
1539 guideB->setEnabled(
false);
1541 loopB->setEnabled(
false);
1550 case GUIDE_CALIBRATION_SUCCESS:
1551 appendLogText(
i18n(
"Calibration completed."));
1553 calibrationComplete =
true;
1561 case GUIDE_CALIBRATION_ERROR:
1567 case GUIDE_CALIBRATING:
1568 clearCalibrationGraphs();
1569 appendLogText(
i18n(
"Calibration started."));
1576 appendLogText(
i18n(
"Guiding resumed."));
1579 appendLogText(
i18n(
"Autoguiding started."));
1591 appendLogText(
i18n(
"Autoguiding aborted."));
1595 case GUIDE_SUSPENDED:
1596 appendLogText(
i18n(
"Guiding suspended."));
1599 case GUIDE_REACQUIRE:
1600 if (guiderType == GUIDE_INTERNAL)
1604 case GUIDE_MANUAL_DITHERING:
1605 appendLogText(
i18n(
"Manual dithering in progress."));
1608 case GUIDE_DITHERING:
1609 appendLogText(
i18n(
"Dithering in progress."));
1612 case GUIDE_DITHERING_SETTLE:
1613 appendLogText(
i18np(
"Post-dither settling for %1 second...",
"Post-dither settling for %1 seconds...",
1614 Options::ditherSettle()));
1617 case GUIDE_DITHERING_ERROR:
1618 appendLogText(
i18n(
"Dithering failed."));
1620 if (guiderType != GUIDE_LINGUIDER)
1623 m_State = GUIDE_ABORTED;
1628 case GUIDE_DITHERING_SUCCESS:
1629 appendLogText(
i18n(
"Dithering completed successfully."));
1631 if (Options::ditherNoGuiding() ==
false)
1633 setStatus(GUIDE_GUIDING);
1635 if (guiderType == GUIDE_INTERNAL)
1644void Guide::updateCCDBin(
int index)
1646 if (m_Camera ==
nullptr || guiderType != GUIDE_INTERNAL)
1649 ISD::CameraChip *targetChip = m_Camera->getChip(useGuideHead ? ISD::CameraChip::GUIDE_CCD :
ISD::CameraChip::PRIMARY_CCD);
1651 targetChip->setBinning(index + 1, index + 1);
1652 guideBinIndex = index;
1654 QVariantMap settings = frameSettings[targetChip];
1655 settings[
"binx"] = index + 1;
1656 settings[
"biny"] = index + 1;
1657 frameSettings[targetChip] = settings;
1659 m_GuiderInstance->setFrameParams(settings[
"x"].toInt(), settings[
"y"].toInt(), settings[
"w"].toInt(), settings[
"h"].toInt(),
1660 settings[
"binx"].toInt(), settings[
"biny"].toInt());
1665 if (m_Camera ==
nullptr || (
prop.getDeviceName() != m_Camera->getDeviceName()) || guiderType != GUIDE_INTERNAL)
1668 if ((
prop.isNameMatch(
"CCD_BINNING") && useGuideHead ==
false) ||
1669 (
prop.isNameMatch(
"GUIDER_BINNING") && useGuideHead))
1672 auto value =
nvp->at(0)->getValue();
1673 if (guideBinIndex > (value - 1))
1675 appendLogText(
i18n(
"%1x%1 guide binning is not supported.", guideBinIndex + 1));
1689 if (guiderType != GUIDE_INTERNAL || targetChip->getCCD() != m_Camera)
1695 ((m_State == GUIDE_GUIDING) || (m_State == GUIDE_DITHERING) || (m_State == GUIDE_CALIBRATING)))
1697 appendLogText(
i18n(
"Exposure failed. Restarting exposure..."));
1698 m_Camera->setEncodingFormat(
"FITS");
1703void Guide::configSEPMultistarOptions()
1706 if (internalGuider->SEPMultiStarEnabled())
1718 auto subframed = m_Settings[
"guideSubframe"];
1722 auto autostar = m_Settings[
"guideAutoStar"];
1734void Guide::saveDefaultGuideExposure()
1736 if(guiderType == GUIDE_PHD2)
1738 phd2Guider->requestSetExposureTime(
guideExposure->value() * 1000);
1739 else if (guiderType == GUIDE_INTERNAL)
1741 internalGuider->setExposureTime();
1753 syncTrackingBoxPosition();
1756void Guide::syncTrackingBoxPosition()
1758 if(!m_Camera || guiderType == GUIDE_LINGUIDER)
1761 if(guiderType == GUIDE_PHD2)
1764 if(!m_ImageData.
isNull())
1766 if(m_ImageData->width() < 50)
1768 m_GuideView->setTrackingBoxEnabled(
false);
1774 ISD::CameraChip *targetChip = m_Camera->getChip(useGuideHead ? ISD::CameraChip::GUIDE_CCD :
ISD::CameraChip::PRIMARY_CCD);
1777 int subBinX = 1, subBinY = 1;
1778 targetChip->getBinning(&subBinX, &subBinY);
1780 if (starCenter.
isNull() ==
false)
1784 targetChip->getFrame(&
x, &
y, &w, &h);
1795 if (subBinX != starCenter.
z())
1797 if (starCenter.
z() > 0)
1799 starCenter.
setX(starCenter.
x() * (starCenter.
z() / subBinX));
1800 starCenter.
setY(starCenter.
y() * (starCenter.
z() / subBinY));
1803 starCenter.
setZ(subBinX);
1808 m_GuideView->setTrackingBoxEnabled(
true);
1809 m_GuideView->setTrackingBox(
starRect);
1817 type = Options::guiderType();
1818 else if (type == guiderType)
1821 if (m_State == GUIDE_CALIBRATING || m_State == GUIDE_GUIDING || m_State == GUIDE_DITHERING)
1823 appendLogText(
i18n(
"Cannot change guider type while active."));
1827 if (m_GuiderInstance !=
nullptr)
1830 if (m_GuiderInstance->isConnected())
1831 m_GuiderInstance->Disconnect();
1837 guiderType =
static_cast<GuiderType
>(type);
1841 case GUIDE_INTERNAL:
1843 connect(internalGuider, &InternalGuider::newMultiPulse,
this, &Guide::sendMultiPulse);
1844 connect(internalGuider, &InternalGuider::newSinglePulse,
this, &Guide::sendSinglePulse);
1846 connect(internalGuider, &InternalGuider::newStarPixmap,
this, &Guide::newStarPixmap);
1848 m_GuiderInstance = internalGuider;
1850 internalGuider->setSquareAlgorithm(opsGuide->kcfg_GuideAlgorithm->currentIndex());
1853 guideB->setEnabled(
true);
1855 loopB->setEnabled(
true);
1857 configSEPMultistarOptions();
1870 l_FOV->setEnabled(
true);
1871 l_FbyD->setEnabled(
true);
1875 updateGuideParams();
1880 if (phd2Guider.isNull())
1881 phd2Guider =
new PHD2();
1883 m_GuiderInstance = phd2Guider;
1884 phd2Guider->setGuideView(m_GuideView);
1890 loopB->setEnabled(
false);
1894 guideB->setEnabled(
false);
1904 l_FOV->setEnabled(
false);
1905 l_FbyD->setEnabled(
false);
1913 if (Options::resetGuideCalibration())
1914 appendLogText(
i18n(
"Warning: Reset Guiding Calibration is enabled. It is recommended to turn this option off for PHD2."));
1916 updateGuideParams();
1919 case GUIDE_LINGUIDER:
1920 if (linGuider.isNull())
1923 m_GuiderInstance = linGuider;
1927 loopB->setEnabled(
false);
1931 guideB->setEnabled(
true);
1942 updateGuideParams();
1947 if (m_GuiderInstance !=
nullptr)
1950 connect(m_GuiderInstance, &Ekos::GuideInterface::newLog,
this, &Ekos::Guide::appendLogText);
1951 connect(m_GuiderInstance, &Ekos::GuideInterface::newStatus,
this, &Ekos::Guide::setStatus);
1952 connect(m_GuiderInstance, &Ekos::GuideInterface::newStarPosition,
this, &Ekos::Guide::setStarPosition);
1953 connect(m_GuiderInstance, &Ekos::GuideInterface::guideStats,
this, &Ekos::Guide::guideStats);
1955 connect(m_GuiderInstance, &Ekos::GuideInterface::newAxisDelta,
this, &Ekos::Guide::setAxisDelta);
1956 connect(m_GuiderInstance, &Ekos::GuideInterface::newAxisPulse,
this, &Ekos::Guide::setAxisPulse);
1957 connect(m_GuiderInstance, &Ekos::GuideInterface::newAxisSigma,
this, &Ekos::Guide::setAxisSigma);
1958 connect(m_GuiderInstance, &Ekos::GuideInterface::newSNR,
this, &Ekos::Guide::setSNR);
1959 connect(m_GuiderInstance, &Ekos::GuideInterface::guideInfo,
this, &Ekos::Guide::guideInfo);
1960 connect(m_GuiderInstance, &Ekos::GuideInterface::abortExposure,
this, &Ekos::Guide::abortExposure);
1965 connect(m_GuiderInstance, &Ekos::GuideInterface::calibrationUpdate,
this, &Ekos::Guide::calibrationUpdate);
1967 connect(m_GuiderInstance, &Ekos::GuideInterface::guideEquipmentUpdated,
this, &Ekos::Guide::configurePHD2Camera);
1973 if (m_GuiderInstance !=
nullptr && guiderType != GUIDE_INTERNAL)
1979 if (m_GuiderInstance !=
nullptr)
1980 m_GuiderInstance->Connect();
1985void Guide::guideInfo(
const QString &info)
1987 if (info.size() == 0)
1999void Guide::updateTrackingBoxSize(
int currentIndex)
2001 if (currentIndex >= 0)
2003 if (guiderType == GUIDE_INTERNAL)
2004 dynamic_cast<InternalGuider *
>(m_GuiderInstance)->setGuideBoxSize(
guideSquareSize->currentText().
toInt());
2006 syncTrackingBoxPosition();
2010void Guide::onThresholdChanged(
int index)
2014 case GUIDE_INTERNAL:
2015 dynamic_cast<InternalGuider *
>(m_GuiderInstance)->setSquareAlgorithm(index);
2023void Guide::onEnableDirRA()
2026 if (Options::gPGEnabled())
2027 m_GuiderInstance->resetGPG();
2030void Guide::onEnableDirDEC()
2032 onControlDirectionChanged();
2035void Guide::onControlDirectionChanged()
2037 if(guiderType == GUIDE_PHD2)
2042void Guide::updateDirectionsFromPHD2(
const QString &mode)
2055 else if(mode ==
"North")
2061 else if(mode ==
"South")
2083 setStarPosition(newStarPosition,
true);
2085 if(guiderType == GUIDE_PHD2)
2088 if(!m_ImageData.
isNull())
2090 if(m_ImageData->width() > 50)
2091 phd2Guider->setLockPosition(starCenter.
x(), starCenter.
y());
2095 if (operationStack.isEmpty() ==
false)
2096 executeOperationStack();
2099void Guide::setAxisDelta(
double ra,
double de)
2118 emit newAxisDelta(ra,
de);
2121void Guide::calibrationUpdate(GuideInterface::CalibrationUpdateType type,
const QString &message,
2122 double dx,
double dy)
2126 case GuideInterface::RA_OUT:
2129 case GuideInterface::RA_IN:
2132 case GuideInterface::BACKLASH:
2135 case GuideInterface::DEC_OUT:
2138 case GuideInterface::DEC_IN:
2141 case GuideInterface::CALIBRATION_MESSAGE_ONLY:
2148void Guide::setAxisSigma(
double ra,
double de)
2152 const double total = std::hypot(ra,
de);
2155 emit newAxisSigma(ra,
de);
2176void Guide::setAxisPulse(
double ra,
double de)
2182void Guide::setSNR(
double snr)
2187void Guide::buildOperationStack(GuideState operation)
2189 operationStack.clear();
2195 operationStack.
push(GUIDE_DARK);
2197 operationStack.
push(GUIDE_CAPTURE);
2198 operationStack.
push(GUIDE_SUBFRAME);
2201 case GUIDE_CALIBRATING:
2202 operationStack.
push(GUIDE_CALIBRATING);
2203 if (guiderType == GUIDE_INTERNAL)
2206 operationStack.
push(GUIDE_DARK);
2211 internalGuider->SEPMultiStarEnabled())
2216 operationStack.
push(GUIDE_CAPTURE);
2218 operationStack.
push(GUIDE_SUBFRAME);
2219 operationStack.
push(GUIDE_STAR_SELECT);
2222 operationStack.
push(GUIDE_CAPTURE);
2225 if (subFramed ==
true &&
guideSubframe->isChecked() ==
false)
2226 operationStack.
push(GUIDE_SUBFRAME);
2233 operationStack.
push(GUIDE_CAPTURE);
2236 operationStack.
push(GUIDE_SUBFRAME);
2239 operationStack.
push(GUIDE_CAPTURE);
2250bool Guide::executeOperationStack()
2252 if (operationStack.isEmpty())
2262 case GUIDE_SUBFRAME:
2274 case GUIDE_STAR_SELECT:
2278 case GUIDE_CALIBRATING:
2279 if (guiderType == GUIDE_INTERNAL)
2281 m_GuiderInstance->setStarPosition(starCenter);
2284 if (m_Mount && m_Mount->canControlTrack() && m_Mount->isTracking() ==
false)
2285 m_Mount->setTrackEnabled(
true);
2288 if (m_GuiderInstance->calibrate())
2290 if (guiderType == GUIDE_INTERNAL)
2296 emit newStatus(GUIDE_CALIBRATION_ERROR);
2297 m_State = GUIDE_IDLE;
2298 appendLogText(
i18n(
"Calibration failed to start."));
2312 return executeOperationStack();
2315bool Guide::executeOneOperation(GuideState operation)
2319 if (m_Camera ==
nullptr)
2322 ISD::CameraChip *targetChip = m_Camera->getChip(useGuideHead ? ISD::CameraChip::GUIDE_CCD :
ISD::CameraChip::PRIMARY_CCD);
2323 if (targetChip ==
nullptr)
2326 int subBinX, subBinY;
2327 targetChip->getBinning(&subBinX, &subBinY);
2331 case GUIDE_SUBFRAME:
2334 if ((guiderType == GUIDE_INTERNAL) && internalGuider->SEPMultiStarEnabled())
2337 if (subFramed ==
false &&
guideSubframe->isChecked() ==
true && targetChip->canSubframe())
2344 int x = starCenter.
x();
2345 int y = starCenter.
y();
2347 x = (
x - offset * 2) * subBinX;
2348 y = (
y - offset * 2) * subBinY;
2349 int w = offset * 4 * subBinX;
2350 int h = offset * 4 * subBinY;
2361 targetChip->setFrame(
x,
y, w, h);
2364 QVariantMap settings = frameSettings[targetChip];
2369 settings[
"binx"] = subBinX;
2370 settings[
"biny"] = subBinY;
2372 frameSettings[targetChip] = settings;
2374 starCenter.
setX(w / (2 * subBinX));
2375 starCenter.
setY(h / (2 * subBinX));
2381 else if (subFramed &&
2383 m_State == GUIDE_REACQUIRE))
2385 targetChip->resetFrame();
2388 targetChip->getFrame(&
x, &
y, &w, &h);
2390 QVariantMap settings;
2395 settings[
"binx"] = subBinX;
2396 settings[
"biny"] = subBinY;
2397 frameSettings[targetChip] = settings;
2401 starCenter.
setX(w / (2 * subBinX));
2402 starCenter.
setY(h / (2 * subBinX));
2415 QVariantMap settings = frameSettings[targetChip];
2416 uint16_t offsetX = 0;
2417 uint16_t offsetY = 0;
2419 if (settings[
"x"].
isValid() &&
2420 settings[
"y"].isValid() &&
2421 settings[
"binx"].isValid() &&
2422 settings[
"biny"].isValid())
2424 offsetX = settings[
"x"].toInt() / settings[
"binx"].toInt();
2425 offsetY = settings[
"y"].toInt() / settings[
"biny"].toInt();
2429 targetChip->setCaptureFilter(FITS_NONE);
2430 m_DarkProcessor->denoise(OpticalTrainManager::Instance()->id(
opticalTrainCombo->currentText()),
2431 targetChip, m_ImageData,
guideExposure->value(), offsetX, offsetY);
2436 case GUIDE_STAR_SELECT:
2438 m_State = GUIDE_STAR_SELECT;
2439 emit newStatus(m_State);
2443 ((guiderType == GUIDE_INTERNAL) &&
2444 internalGuider->SEPMultiStarEnabled()))
2449 appendLogText(
i18n(
"Auto star selected."));
2453 appendLogText(
i18n(
"Failed to select an auto star."));
2455 m_State = GUIDE_CALIBRATION_ERROR;
2456 emit newStatus(m_State);
2462 appendLogText(
i18n(
"Select a guide star to calibrate."));
2475void Guide::processGuideOptions()
2477 if (Options::guiderType() != guiderType)
2479 guiderType =
static_cast<GuiderType
>(Options::guiderType());
2484void Guide::showFITSViewer()
2494 connect(fv.
get(), &FITSViewer::terminated,
this, [
this]()
2506void Guide::setExternalGuiderBLOBEnabled(
bool enable)
2509 if (guiderType == GUIDE_INTERNAL)
2515 m_Camera->setBLOBEnabled(enable);
2517 if(m_Camera->isBLOBEnabled())
2519 checkUseGuideHead();
2521 auto targetChip = m_Camera->getChip(useGuideHead ? ISD::CameraChip::GUIDE_CCD :
ISD::CameraChip::PRIMARY_CCD);
2523 targetChip->setCaptureMode(FITS_GUIDE);
2529void Guide::resetNonGuidedDither()
2532 nonGuidedDitherRaOffsetMsec = 0;
2533 nonGuidedDitherDecOffsetMsec = 0;
2537 if (!isNonGuidedDitherInitialized)
2539 auto seed = std::chrono::system_clock::now().time_since_epoch().count();
2540 nonGuidedPulseGenerator.seed(seed);
2541 isNonGuidedDitherInitialized =
true;
2542 qCDebug(
KSTARS_EKOS_GUIDE) <<
"Initialize non guiding dithering random generator";
2546void Guide::nonGuidedDither()
2548 double ditherPulse = Options::ditherNoGuidingPulse();
2574 decMsec, DontCaptureAfterPulses);
2581 emit newStatus(GUIDE_DITHERING_SUCCESS);
2582 m_State = GUIDE_IDLE;
2588 emit newStatus(GUIDE_DITHERING_ERROR);
2589 m_State = GUIDE_IDLE;
2593void Guide::handleManualDither()
2595 ISD::CameraChip *targetChip = m_Camera->getChip(useGuideHead ? ISD::CameraChip::GUIDE_CCD :
ISD::CameraChip::PRIMARY_CCD);
2596 if (targetChip ==
nullptr)
2603 if (guiderType != GUIDE_INTERNAL)
2624 m_GuiderInstance->dither(
ditherDialog.magnitude->value());
2627 InternalGuider *
const ig =
dynamic_cast<InternalGuider *
>(m_GuiderInstance);
2634bool Guide::connectGuider()
2636 setStatus(GUIDE_IDLE);
2637 return m_GuiderInstance->Connect();
2640bool Guide::disconnectGuider()
2642 return m_GuiderInstance->Disconnect();
2645void Guide::initPlots()
2648 initCalibrationPlot();
2656void Guide::initDriftGraph()
2666 driftGraph->setCorrectionGraphScale(correctionSlider->value());
2677void Guide::initCalibrationPlot()
2724 QPen(KStarsData::Instance()->colorScheme()->colorNamed(
"RAGuideError"), 2),
QBrush(), 6));
2738 calibrationPlot->graph(GuideGraph::G_RA_HIGHLIGHT)->setName(
"Backlash");
2743 QPen(KStarsData::Instance()->colorScheme()->colorNamed(
"DEGuideError"), 2),
QBrush(), 6));
2744 calibrationPlot->graph(GuideGraph::G_DEC_HIGHLIGHT)->setName(
"DEC out");
2754 calLabel->setColor(
QColor(255, 255, 255));
2757 calLabel->position->setCoords(0.5, 0);
2758 calLabel->setText(
"");
2759 calLabel->setFont(
QFont(font().family(), 10));
2760 calLabel->setVisible(
true);
2766void Guide::initView()
2768 guideStateWidget =
new GuideStateWidget();
2774 m_GuideView->createFloatingToolBar();
2776 vlayout->addWidget(m_GuideView.get());
2783void Guide::initConnections()
2786 captureTimeout.setSingleShot(
true);
2790 m_DebounceTimer.setInterval(500);
2791 m_DebounceTimer.setSingleShot(
true);
2796 &Ekos::Guide::updateTrackingBoxSize);
2801 if(guiderType != GUIDE_PHD2)
2806 &Ekos::Guide::updateCCDBin);
2821 m_State = GUIDE_CAPTURE;
2822 emit newStatus(m_State);
2824 if(guiderType == GUIDE_PHD2)
2826 configurePHD2Camera();
2827 if(phd2Guider->isCurrentCameraNotInEkos())
2829 i18n(
"The PHD2 camera is not available to Ekos, so you cannot see the captured images. But you will still see the Guide Star Image when you guide."));
2833 i18n(
"To receive PHD2 images other than the Guide Star Image, SubFrame must be unchecked. Unchecking it now to enable your image captures. You can re-enable it before Guiding"));
2836 phd2Guider->captureSingleFrame();
2838 else if (guiderType == GUIDE_INTERNAL)
2859 m_GuiderInstance->Connect();
2864 m_GuiderInstance->Disconnect();
2868 m_PulseTimer.setSingleShot(
true);
2873 &Ekos::Guide::buildTarget);
2878 driftGraph->toggleShowPlot(GuideGraph::G_RA, isChecked);
2882 driftGraph->toggleShowPlot(GuideGraph::G_DEC, isChecked);
2886 driftGraph->toggleShowPlot(GuideGraph::G_RA_PULSE, isChecked);
2890 driftGraph->toggleShowPlot(GuideGraph::G_DEC_PULSE, isChecked);
2894 driftGraph->toggleShowPlot(GuideGraph::G_SNR, isChecked);
2898 driftGraph->toggleShowPlot(GuideGraph::G_RMS, isChecked);
2904 connect(
this, &Ekos::Guide::newStatus, guideStateWidget, &Ekos::GuideStateWidget::updateGuideStatus);
2909 auto name = device->getDeviceName();
2911 device->disconnect(
this);
2914 if (m_Mount && m_Mount->getDeviceName() == name)
2916 m_Mount->disconnect(
this);
2922 if (m_Camera && m_Camera->getDeviceName() == name)
2924 m_Camera->disconnect(
this);
2930 if (m_Guider && m_Guider->getDeviceName() == name)
2932 m_Guider->disconnect(
this);
2938 if (m_AO && m_AO->getDeviceName() == name)
2940 m_AO->disconnect(
this);
2947 m_State = GUIDE_LOOPING;
2948 emit newStatus(m_State);
2950 if(guiderType == GUIDE_PHD2)
2952 configurePHD2Camera();
2953 if(phd2Guider->isCurrentCameraNotInEkos())
2955 i18n(
"The PHD2 camera is not available to Ekos, so you cannot see the captured images. But you will still see the Guide Star Image when you guide."));
2959 i18n(
"To receive PHD2 images other than the Guide Star Image, SubFrame must be unchecked. Unchecking it now to enable your image captures. You can re-enable it before Guiding"));
2963 stopB->setEnabled(
true);
2965 else if (guiderType == GUIDE_INTERNAL)
2972QVariantMap Guide::getAllSettings()
const
2974 QVariantMap settings;
2998void Guide::setAllSettings(
const QVariantMap &settings)
3002 disconnectSettings();
3004 for (
auto &name : settings.keys())
3010 syncControl(settings, name, comboBox);
3018 syncControl(settings, name, doubleSpinBox);
3026 syncControl(settings, name,
spinBox);
3034 syncControl(settings, name,
checkbox);
3040 for (
auto &key : settings.keys())
3042 auto value = settings[key];
3044 Options::self()->setProperty(key.toLatin1(), value);
3046 m_Settings[key] = value;
3047 m_GlobalSettings[key] = value;
3050 emit settingsUpdated(getAllSettings());
3053 OpticalTrainSettings::Instance()->setOpticalTrainID(OpticalTrainManager::Instance()->
id(
opticalTrainCombo->currentText()));
3054 OpticalTrainSettings::Instance()->setOneSetting(OpticalTrainSettings::Guide, m_Settings);
3063bool Guide::syncControl(
const QVariantMap &settings,
const QString &key,
QWidget * widget)
3074 const int value = settings[key].toInt(&ok);
3077 pSB->setValue(value);
3083 const double value = settings[key].toDouble(&ok);
3086 pDSB->setValue(value);
3092 const bool value = settings[key].toBool();
3093 if (value !=
pCB->isChecked())
3099 const bool value = settings[key].toBool();
3107 const QString value = settings[key].toString();
3115void Guide::setupOpticalTrainManager()
3117 connect(OpticalTrainManager::Instance(), &OpticalTrainManager::updated,
this, &Guide::refreshOpticalTrain);
3124 if (guiderType == GUIDE_PHD2 && m_GuiderInstance->isConnected())
3126 appendLogText(i18n(
"Cannot change active optical train while PHD2 is connected"));
3130 ProfileSettings::Instance()->setOneSetting(ProfileSettings::GuideOpticalTrain,
3132 refreshOpticalTrain();
3133 emit trainChanged();
3137void Guide::refreshOpticalTrain()
3142 trainB->setEnabled(
true);
3144 QVariant trainID = ProfileSettings::Instance()->getOneSetting(ProfileSettings::GuideOpticalTrain);
3148 auto id = trainID.
toUInt();
3151 if (OpticalTrainManager::Instance()->exists(
id) ==
false)
3157 auto name = OpticalTrainManager::Instance()->name(
id);
3161 auto scope = OpticalTrainManager::Instance()->getScope(name);
3162 m_FocalLength = scope[
"focal_length"].toDouble(-1);
3163 m_Aperture = scope[
"aperture"].toDouble(-1);
3164 m_FocalRatio = scope[
"focal_ratio"].toDouble(-1);
3165 m_Reducer = OpticalTrainManager::Instance()->getReducer(name);
3169 m_Aperture = m_FocalLength / m_FocalRatio;
3171 auto mount = OpticalTrainManager::Instance()->getMount(name);
3174 auto camera = OpticalTrainManager::Instance()->getCamera(name);
3177 if (guiderType == GUIDE_INTERNAL)
3180 camera->setScopeInfo(m_FocalLength * m_Reducer, m_Aperture);
3185 syncTelescopeInfo();
3187 auto guider = OpticalTrainManager::Instance()->getGuider(name);
3190 auto ao = OpticalTrainManager::Instance()->getAdaptiveOptics(name);
3191 setAdaptiveOptics(ao);
3194 OpticalTrainSettings::Instance()->setOpticalTrainID(
id);
3195 auto settings = OpticalTrainSettings::Instance()->getOneSetting(OpticalTrainSettings::Guide);
3196 if (settings.isValid())
3198 auto map = settings.toJsonObject().toVariantMap();
3199 if (map != m_Settings)
3200 setAllSettings(map);
3203 m_Settings = m_GlobalSettings;
3209void Guide::loadGlobalSettings()
3214 QVariantMap settings;
3218 if (
oneWidget->objectName() ==
"opticalTrainCombo")
3222 value = Options::self()->property(key.
toLatin1());
3226 settings[key] = value;
3234 value = Options::self()->property(key.
toLatin1());
3238 settings[key] = value;
3246 value = Options::self()->property(key.
toLatin1());
3250 settings[key] = value;
3258 value = Options::self()->property(key.
toLatin1());
3262 settings[key] = value;
3266 m_GlobalSettings = m_Settings = settings;
3269void Guide::connectSettings()
3295void Guide::disconnectSettings()
3322 Options::self()->setProperty(key.
toLatin1(), value);
3323 m_Settings[key] = value;
3324 m_GlobalSettings[key] = value;
3326 m_DebounceTimer.start();
3332void Guide::settleSettings()
3334 Options::self()->save();
3335 emit settingsUpdated(getAllSettings());
3337 OpticalTrainSettings::Instance()->setOpticalTrainID(OpticalTrainManager::Instance()->
id(
opticalTrainCombo->currentText()));
3338 OpticalTrainSettings::Instance()->setOneSetting(OpticalTrainSettings::Guide, m_Settings);
3341void Guide::syncSettings()
3354 key =
dsb->objectName();
3355 value =
dsb->value();
3361 value = sb->
value();
3370 key =
cbox->objectName();
3371 value =
cbox->currentText();
3375 key =
rb->objectName();
3379 updateSetting(key, value);
Q_SCRIPTABLE bool calibrate()
DBUS interface function.
void updateProperty(INDI::Property prop)
processCCDNumber Process number properties arriving from CCD.
Q_SCRIPTABLE Q_NOREPLY void setAutoStarEnabled(bool enable)
DBUS interface function.
Q_SCRIPTABLE Q_NOREPLY void setDarkFrameEnabled(bool enable)
DBUS interface function.
void processData(const QSharedPointer< FITSData > &data)
newFITS is called by the INDI framework whenever there is a new BLOB arriving
Q_SCRIPTABLE bool resume()
DBUS interface function.
void setTrackingStar(int x, int y)
setTrackingStar Gets called when the user select a star in the guide frame
Q_SCRIPTABLE bool setGuiderType(int type)
DBUS interface function.
void checkExposureValue(ISD::CameraChip *targetChip, double exposure, IPState expState)
checkExposureValue This function is called by the INDI framework whenever there is a new exposure val...
void updateSetting(const QString &key, const QVariant &value)
updateSetting Update per-train and global setting
bool setGuider(ISD::Guider *device)
Add new Guider.
Q_SCRIPTABLE bool suspend()
DBUS interface function.
Q_SCRIPTABLE bool dither()
DBUS interface function.
Q_SCRIPTABLE Q_NOREPLY void setExposure(double value)
DBUS interface function.
Q_SCRIPTABLE Q_NOREPLY void setSubFrameEnabled(bool enable)
DBUS interface function.
void checkCamera()
checkCamera Check all CCD parameters and ensure all variables are updated to reflect the selected CCD
Q_SCRIPTABLE bool capture()
DBUS interface function.
Q_SCRIPTABLE Q_NOREPLY void clearCalibration()
DBUS interface function.
Q_SCRIPTABLE bool abort()
DBUS interface function.
bool setAdaptiveOptics(ISD::AdaptiveOptics *device)
Add new Adaptive Optics.
void setDECSwap(bool enable)
setDECSwap Change ST4 declination pulse direction.
void clearLog()
clearLog As the name suggests
Q_SCRIPTABLE bool guide()
DBUS interface function.
Uses external LinGuider for guiding.
Uses external PHD2 for guiding.
The main change relative to fitsview is to add the capability of displaying the 'neighbor guide stars...
Guide is a special class that handles ST4 commands.
AdaptiveOptics class handles control of INDI AdaptiveOptics devices.
CameraChip class controls a particular chip in camera.
Camera class controls an INDI Camera device.
device handle controlling Mounts.
KPageWidgetItem * addPage(QWidget *page, const QString &itemName, const QString &pixmapName=QString(), const QString &header=QString(), bool manage=true)
void setIcon(const QIcon &icon)
static KStars * Instance()
void colorSchemeChanged()
DBUS interface notification.
Manages a single axis inside a QCustomPlot.
void rangeChanged(const QCPRange &newRange)
Q_SLOT void setRange(const QCPRange &range)
@ lsNone
data points are not connected with any lines (e.g.
@ ptAxisRectRatio
Static positioning given by a fraction of the axis rect size (see setAxisRect).
@ ptPlotCoords
Dynamic positioning at a plot coordinate defined by two axes (see setAxes).
void setText(const QString &text)
Represents the range an axis is encompassing.
Represents the visual appearance of scatter points.
@ ssDisc
\enumimage{ssDisc.png} a circle which is filled with the pen's color (not the brush as with ssCircle)
@ ssPlus
\enumimage{ssPlus.png} a plus
@ ssCircle
\enumimage{ssCircle.png} a circle
void mouseMove(QMouseEvent *event)
void mousePress(QMouseEvent *event)
The QProgressIndicator class lets an application display a progress indicator to show that a long tas...
void stopAnimation()
Stops the spin animation.
void startAnimation()
Starts the spin animation.
bool isAnimated() const
Returns a Boolean value indicating whether the component is currently animated.
The sky coordinates of a point in the sky.
An angle, stored as degrees, but expressible in many ways.
QString i18np(const char *singular, const char *plural, const TYPE &arg...)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
char * toString(const EngineQuery &query)
Ekos is an advanced Astrophotography tool for Linux.
CaptureState
Capture states.
ISD is a collection of INDI Standard Devices.
KIOCORE_EXPORT SimpleJob * mount(bool ro, const QByteArray &fstype, const QString &dev, const QString &point, JobFlags flags=DefaultFlags)
bool isValid(QStringView ifopt)
QString name(StandardShortcut id)
@ iRangeDrag
0x001 Axis ranges are draggable (see QCPAxisRect::setRangeDrag, QCPAxisRect::setRangeDragAxes)
@ iRangeZoom
0x002 Axis ranges are zoomable with the mouse wheel (see QCPAxisRect::setRangeZoom,...
void sliderMoved(int value)
void activated(int index)
void currentIndexChanged(int index)
bool registerObject(const QString &path, QObject *object, RegisterOptions options)
QDBusConnection sessionBus()
void valueChanged(double d)
qint64 elapsed() const const
QIcon fromTheme(const QString &name)
iterator insert(const_iterator before, parameter_type value)
bool contains(const Key &key) const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool disconnect(const QMetaObject::Connection &connection)
bool isNull() const const
void splitterMoved(int pos, int index)
QString arg(Args &&... args) const const
QString number(double n, char format, int precision)
QByteArray toLatin1() const const
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QUrl fromLocalFile(const QString &localFile)
bool isValid() const const
bool toBool() const const
double toDouble(bool *ok) const const
int toInt(bool *ok) const const
QString toString() const const
uint toUInt(bool *ok) const const
bool isNull() const const