8#include "opsmiscsettings.h"
9#include "opsdslrsettings.h"
10#include <KConfigDialog>
12#include "cameraprocess.h"
13#include "camerastate.h"
14#include "capturedeviceadaptor.h"
15#include "captureadaptor.h"
16#include "refocusstate.h"
18#include "kstarsdata.h"
20#include "sequencejob.h"
21#include "placeholderpath.h"
22#include "ekos/manager.h"
23#include "ekos/auxiliary/darklibrary.h"
24#include "ekos/auxiliary/opticaltrainmanager.h"
25#include "ekos/auxiliary/profilesettings.h"
26#include "auxiliary/ksmessagebox.h"
28#include "scriptsmanager.h"
29#include "fitsviewer/fitsdata.h"
30#include "indi/driverinfo.h"
31#include "indi/indifilterwheel.h"
32#include "indi/indicamera.h"
33#include "indi/indirotator.h"
34#include "ekos/guide/guide.h"
35#include <basedevice.h>
37#include <ekos_capture_debug.h>
40#define MF_TIMER_TIMEOUT 90000
41#define MF_RA_DIFF_LIMIT 4
46#define KEY_FILTERS "filtersList"
47#define TAB_BUTTON_SIZE 20
56 qRegisterMetaType<CaptureState>(
"CaptureState");
57 qDBusRegisterMetaType<CaptureState>();
58 new CaptureAdaptor(
this);
60 m_moduleState.reset(
new CaptureModuleState());
64 QPushButton *addButton =
new QPushButton;
66 addButton->
setFixedSize(TAB_BUTTON_SIZE, TAB_BUTTON_SIZE);
67 addButton->
setToolTip(
i18n(
"<p>Add additional camera</p><p><b>WARNING</b>: This feature is experimental!</p>"));
70 cameraTabs->addTab(newTab,
"");
78 QPointer<QDBusInterface> ekosInterface =
new QDBusInterface(
"org.kde.kstars",
"/KStars/Ekos",
"org.kde.kstars.Ekos",
88 DarkLibrary::Instance()->setCaptureModule(
this);
91 connect(m_moduleState.get(), &CaptureModuleState::dither,
this, &Capture::dither);
92 connect(m_moduleState.get(), &CaptureModuleState::newLog,
this, &Capture::appendLogText);
106 m_OpsMiscSettings =
new OpsMiscSettings();
110 m_OpsDslrSettings =
new OpsDslrSettings();
111 page = dialog->
addPage(m_OpsDslrSettings,
i18n(
"DSLR"));
119 newCamera.
reset(
new Camera(cameras().count(),
false,
nullptr));
122 const int tabIndex = cameraTabs->insertTab(std::max(0, cameraTabs->count() - 1), newCamera.
get(),
"new Camera");
123 cameraTabs->setCurrentIndex(tabIndex);
129 connect(newCamera.
get(), &Camera::newLog,
this, &Capture::appendLogText);
131 connect(newCamera.
get(), &Camera::sequenceChanged,
this, &Capture::sequenceChanged);
132 connect(newCamera.
get(), &Camera::newLocalPreview,
this, &Capture::newLocalPreview);
133 connect(newCamera.
get(), &Camera::dslrInfoRequested,
this, &Capture::dslrInfoRequested);
134 connect(newCamera.
get(), &Camera::trainChanged,
this, &Capture::trainChanged);
135 connect(newCamera.
get(), &Camera::settingsUpdated,
this, &Capture::settingsUpdated);
136 connect(newCamera.
get(), &Camera::filterManagerUpdated,
this, &Capture::filterManagerUpdated);
137 connect(newCamera.
get(), &Camera::newFilterStatus,
this, &Capture::newFilterStatus);
138 connect(newCamera.
get(), &Camera::ready,
this, &Capture::ready);
139 connect(newCamera.
get(), &Camera::newExposureProgress,
this, &Capture::newExposureProgress);
140 connect(newCamera.
get(), &Camera::captureComplete,
this, &Capture::captureComplete);
141 connect(newCamera.
get(), &Camera::captureStarting,
this, &Capture::captureStarting);
142 connect(newCamera.
get(), &Camera::captureAborted,
this, &Capture::captureAborted);
143 connect(newCamera.
get(), &Camera::checkFocus,
this, &Capture::checkFocus);
144 connect(newCamera.
get(), &Camera::newImage,
this, &Capture::newImage);
145 connect(newCamera.
get(), &Camera::runAutoFocus,
this, &Capture::runAutoFocus);
146 connect(newCamera.
get(), &Camera::resetFocusFrame,
this, &Capture::resetFocusFrame);
147 connect(newCamera.
get(), &Camera::abortFocus,
this, &Capture::abortFocus);
148 connect(newCamera.
get(), &Camera::adaptiveFocus,
this, &Capture::adaptiveFocus);
149 connect(newCamera.
get(), &Camera::meridianFlipStarted,
this, &Capture::meridianFlipStarted);
150 connect(newCamera.
get(), &Camera::captureTarget,
this, &Capture::captureTarget);
151 connect(newCamera.
get(), &Camera::guideAfterMeridianFlip,
this, &Capture::guideAfterMeridianFlip);
152 connect(newCamera.
get(), &Camera::newStatus,
this, &Capture::newStatus);
153 connect(newCamera.
get(), &Camera::suspendGuiding,
this, &Capture::suspendGuiding);
154 connect(newCamera.
get(), &Camera::resumeGuiding,
this, &Capture::resumeGuiding);
155 connect(newCamera.
get(), &Camera::resetNonGuidedDither,
this, &Capture::resetNonGuidedDither);
156 connect(newCamera.
get(), &Camera::driverTimedout,
this, &Capture::driverTimedout);
159 const QString train = tabIndex == 0 ?
"" : findUnusedOpticalTrain();
162 newCamera->opticalTrainCombo->setCurrentText(train);
164 moduleState()->addCamera(newCamera);
171const QString Capture::findUnusedOpticalTrain()
173 QList<QString> names = OpticalTrainManager::Instance()->getTrainNames();
174 foreach(
auto cam, cameras())
180 return names.
first();
187 if (tabID < cameraTabs->count() && tabID < cameras().count())
189 auto cam = moduleState()->mutableCameras()[tabID];
191 if (cam->activeCamera() !=
nullptr)
193 auto name = cam->activeCamera()->getDeviceName();
194 cameraTabs->setTabText(tabID, name);
198 cam->state()->getRefocusState()->setForceInSeqAF(moduleState()->forceInSeqAF(cam->opticalTrain()));
201 qCWarning(KSTARS_EKOS_CAPTURE) <<
"Unknown camera ID:" << tabID;
204 cameraTabs->setTabText(cameraTabs->currentIndex(),
"no camera");
210 return process()->setDome(device);
215 if (mainCamera()->m_standAlone)
217 if (name ==
"Mount" && mountInterface ==
nullptr)
219 qCDebug(KSTARS_EKOS_CAPTURE) <<
"Registering new Module (" << name <<
")";
220 mountInterface =
new QDBusInterface(
"org.kde.kstars",
"/KStars/Ekos/Mount",
227 if (mainCameraDevices()->getActiveCamera())
228 return mainCameraDevices()->getActiveCamera()->getDeviceName();
240 if (!mainCameraDevices()->getActiveCamera())
243 mainCameraState()->setSuspendGuidingOnDownload((mainCameraDevices()->getActiveCamera()->getChip(
244 ISD::CameraChip::GUIDE_CCD) == guideChip) ||
245 (guideChip->getCCD() == mainCameraDevices()->getActiveCamera() &&
246 mainCameraDevices()->getActiveCamera()->getDriverInfo()->getAuxInfo().value(
"mdpd",
false).toBool()));
252 for (
auto &cam : cameras())
253 if (trainname ==
"" || cam->opticalTrain() == trainname)
254 cam->setFocusStatus(newstate);
260 for (
auto &cam : cameras())
261 if (trainname ==
"" || cam->opticalTrain() == trainname)
262 cam->focusAdaptiveComplete(success);
267 if (mainCameraDevices()->filterWheel())
268 return mainCameraDevices()->filterWheel()->getDeviceName();
275 if (mainCameraDevices()->filterWheel())
277 mainCamera()->FilterPosCombo->setCurrentText(filter);
286 return mainCamera()->FilterPosCombo->currentText();
297 if (mainCamera()->opticalTrain() != train)
298 mainCamera()->selectOpticalTrain(train);
312 return cam->loadSequenceQueue(fileURL, targetName);
316void Capture::appendLogText(
const QString &text)
318 m_LogText.
insert(0,
i18nc(
"log entry; %1 is the date, %2 is the text",
"%1 %2",
319 KStarsData::Instance()->lt().toString(
"yyyy-MM-ddThh:mm:ss"), text));
321 qCInfo(KSTARS_EKOS_CAPTURE) << text;
326void Capture::clearLog()
334 Q_UNUSED(absTemperture);
336 for (
auto &cam : cameras())
337 if (trainname ==
"" || cam->opticalTrain() == trainname)
338 cam->state()->getRefocusState()->setFocusTemperatureDelta(focusTemperatureDelta);
344 moduleState()->setGuideDeviation(delta_ra, delta_dec);
351 mainCameraState()->setIgnoreJobProgress(
true);
364 qCWarning(KSTARS_EKOS_CAPTURE) <<
"Cannot set the captured frames map for train" << train;
369 cam->state()->setCapturedFramesCount(signature, count);
372void Capture::setAlignStatus(
AlignState newstate)
375 mainCameraState()->setAlignState(newstate);
378void Capture::setGuideStatus(GuideState newstate)
381 moduleState()->setGuideStatus(newstate);
386 if (mainCameraDevices()->getActiveCamera() ==
nullptr)
389 return mainCameraDevices()->getActiveCamera()->setStreamLimits(maxBufferSize, maxPreviewFPS);
403 qCWarning(KSTARS_EKOS_CAPTURE) <<
"Cannot start capturing for train" << train;
412 return cam->opticalTrain();
419 for (
auto cam : cameras())
426 qCWarning(KSTARS_EKOS_CAPTURE) <<
"Cannot abort capturing for train" << train;
439 if (i < cameras().count())
440 return moduleState()->mutableCameras()[i];
443 qCWarning(KSTARS_EKOS_CAPTURE) <<
"Unknown camera ID:" << i;
444 return moduleState()->mutableCameras()[0];
448void Ekos::Capture::closeCameraTab(
int tabIndex)
450 cameraTabs->removeTab(tabIndex);
451 moduleState()->removeCamera(tabIndex);
453 cameraTabs->setCurrentIndex(std::max(0, tabIndex - 1));
456void Capture::checkCloseCameraTab(
int tabIndex)
459 if (tabIndex == cameraTabs->count() - 1)
462 if (moduleState()->mutableCameras()[tabIndex]->state()->isBusy())
468 moduleState()->mutableCameras()[tabIndex]->abort();
469 closeCameraTab(tabIndex);
477 KSMessageBox::Instance()->warningContinueCancel(
i18n(
"Camera %1 is busy. Abort to close?",
478 moduleState()->mutableCameras()[tabIndex]->activeCamera()->getDeviceName()),
i18n(
"Stop capturing"), 30,
false,
483 closeCameraTab(tabIndex);
487const QSharedPointer<Camera> Capture::mainCamera()
const
489 if (cameras().
size() > 0)
490 return moduleState()->cameras()[0];
493 QSharedPointer<CaptureModuleState> cms;
494 cms.
reset(
new CaptureModuleState());
497 return QSharedPointer<Camera>(
new Camera(0));
503 for (
auto &cam : cameras())
505 if (cam->opticalTrain() == train)
506 return cam->m_cameraId;
513 cam->selectOpticalTrain(train);
514 return cam->m_cameraId;
520void Capture::setMountStatus(ISD::Mount::Status newState)
524 case ISD::Mount::MOUNT_PARKING:
525 case ISD::Mount::MOUNT_SLEWING:
526 case ISD::Mount::MOUNT_MOVING:
527 mainCamera()->previewB->setEnabled(
false);
528 mainCamera()->liveVideoB->setEnabled(
false);
532 if (mainCameraState()->isBusy() ==
false)
533 mainCamera()->startB->setEnabled(
false);
537 if (mainCameraState()->isBusy() ==
false)
539 mainCamera()->previewB->setEnabled(
true);
540 if (mainCameraDevices()->getActiveCamera())
541 mainCamera()->liveVideoB->setEnabled(mainCameraDevices()->getActiveCamera()->hasVideoStream());
542 mainCamera()->startB->setEnabled(
true);
549void Capture::setAlignResults(
double solverPA,
double ra,
double de,
double pixscale)
554 if (mainCameraDevices()->rotator() && mainCamera()->m_RotatorControlPanel)
555 mainCamera()->m_RotatorControlPanel->refresh(solverPA);
558void Capture::setMeridianFlipState(QSharedPointer<MeridianFlipState> newstate)
560 mainCameraState()->setMeridianFlipState(newstate);
561 connect(mainCameraState()->getMeridianFlipState().
get(), &MeridianFlipState::newLog,
this, &Capture::appendLogText);
562 connect(mainCameraState()->getMeridianFlipState().
get(), &MeridianFlipState::newMountMFStatus, moduleState().
get(),
563 &CaptureModuleState::updateMFMountState);
569 for (
auto &cam : cameras())
570 if (cam->process()->hasCoolerControl())
571 result |= cam->process()->hasCoolerControl();
578 for (
auto &cam : cameras())
579 if (cam->process()->hasCoolerControl())
580 result &= cam->process()->setCoolerControl(enable);
587 process()->removeDevice(device);
590QString Capture::getTargetName()
593 return activeJob()->getCoreProperty(SequenceJob::SJ_TargetName).
toString();
601 for (
auto &cam : cameras())
602 if (trainname ==
"" || cam->opticalTrain() == trainname)
603 cam->state()->getRefocusState()->setFocusHFR(newHFR, inAutofocus);
609 for (
auto &cam : cameras())
610 if (trainname ==
"" || cam->opticalTrain() == trainname)
612 cam->state()->getRefocusState()->setForceInSeqAF(requested);
614 moduleState()->setForceInSeqAF(requested, trainname);
void setHFR(double newHFR, int position, bool inAutofocus, const QString &trainname)
setHFR Receive the measured HFR value of the latest frame
bool setVideoLimits(uint16_t maxBufferSize, uint16_t maxPreviewFPS)
setVideoLimits sets the buffer size and max preview fps for live preview
bool setDome(ISD::Dome *device)
setDome Set dome device
void updateCamera(int tabID, bool isValid)
Update the camera.
void inSequenceAFRequested(bool requested, const QString &trainname)
inSequenceAFRequested Focuser informs that the user wishes an AF run as soon as possible.
QSharedPointer< CameraProcess > process() const
process shortcut for the process engine
void setFocusStatus(FocusState newstate, const QString &trainname)
setFocusStatus Forward the new focus state to the capture module state machine
void setFocusTemperatureDelta(double focusTemperatureDelta, double absTemperature, const QString &trainname)
setFocusTemperatureDelta update the focuser's temperature delta
void setGuideDeviation(double delta_ra, double delta_dec)
setGuideDeviation Set the guiding deviation as measured by the guiding module.
void registerNewModule(const QString &name)
registerNewModule Register an Ekos module as it arrives via DBus and create the appropriate DBus inte...
void focusAdaptiveComplete(bool success, const QString &trainname)
focusAdaptiveComplete Forward the new focus state to the capture module state machine
int findCamera(QString train, bool addIfNecessary)
find the camera using the given train
void removeDevice(const QSharedPointer< ISD::GenericDevice > &device)
Generic method for removing any connected device.
CameraChip class controls a particular chip in camera.
Class handles control of INDI dome devices.
KPageWidgetItem * addPage(QWidget *page, const QString &itemName, const QString &pixmapName=QString(), const QString &header=QString(), bool manage=true)
void setIcon(const QIcon &icon)
Q_SCRIPTABLE bool hasCoolerControl()
DBUS interface function.
Q_SCRIPTABLE Q_NOREPLY void abort(QString train="")
DBUS interface function.
Q_SCRIPTABLE Q_NOREPLY void ignoreSequenceHistory()
DBUS interface function.
void setupOptions()
prepareGUI Perform once only GUI prep processing
Q_SCRIPTABLE QString start(QString train="")
DBUS interface function.
Q_SCRIPTABLE bool loadSequenceQueue(const QString &fileURL, QString train="", bool isLead=true, QString targetName="")
DBUS interface function.
Q_SCRIPTABLE bool setCoolerControl(bool enable)
DBUS interface function.
Q_SCRIPTABLE bool setFilter(const QString &filter)
DBUS interface function.
Q_SCRIPTABLE Q_NOREPLY void setCapturedFramesMap(const QString &signature, int count, QString train="")
DBUS interface function.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
Ekos is an advanced Astrophotography tool for Linux.
KIOCORE_EXPORT TransferJob * get(const QUrl &url, LoadType reload=NoReload, JobFlags flags=DefaultFlags)
bool connect(const QString &service, const QString &path, const QString &interface, const QString &name, QObject *receiver, const char *slot)
bool registerObject(const QString &path, QObject *object, RegisterOptions options)
QDBusConnection sessionBus()
QIcon fromTheme(const QString &name)
iterator insert(const_iterator before, parameter_type value)
bool isEmpty() const const
qsizetype removeAll(const AT &t)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool disconnect(const QMetaObject::Connection &connection)
QString toString() const const