Warning, file /education/kstars/kstars/ekos/align/align.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2013 Jasem Mutlaq <mutlaqja@ikarustech.com> 0003 SPDX-FileCopyrightText: 2013-2021 Jasem Mutlaq <mutlaqja@ikarustech.com> 0004 SPDX-FileCopyrightText: 2018-2020 Robert Lancaster <rlancaste@gmail.com> 0005 SPDX-FileCopyrightText: 2019-2021 Hy Murveit <hy@murveit.com> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #pragma once 0011 0012 #include "ui_align.h" 0013 #include "ekos/ekos.h" 0014 #include "indi/indicamera.h" 0015 #include "indi/indistd.h" 0016 #include "indi/indimount.h" 0017 #include "skypoint.h" 0018 0019 #include <QTime> 0020 #include <QTimer> 0021 #include <QElapsedTimer> 0022 #include <KConfigDialog> 0023 0024 #if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0) 0025 #include <qtdbusglobal.h> 0026 #else 0027 #include <qdbusmacros.h> 0028 #endif 0029 0030 #include <stellarsolver.h> 0031 #include <memory> 0032 0033 class QProgressIndicator; 0034 0035 class AlignView; 0036 class FOV; 0037 class StarObject; 0038 class ProfileInfo; 0039 class RotatorSettings; 0040 0041 namespace Ekos 0042 { 0043 class AstrometryParser; 0044 class DarkProcessor; 0045 class FilterManager; 0046 class RemoteAstrometryParser; 0047 class OpsAstrometry; 0048 class OpsAlign; 0049 class StellarSolverProfileEditor; 0050 class OpsPrograms; 0051 class OpsASTAP; 0052 class OpsAstrometryIndexFiles; 0053 class MountModel; 0054 class PolarAlignmentAssistant; 0055 class ManualRotator; 0056 0057 /** 0058 *@class Align 0059 *@short Align class handles plate-solving and polar alignment measurement and correction using astrometry.net 0060 * The align class employs StellarSolver library for local solvers and supports remote INDI-based solver. 0061 * StellarSolver supports internal and external solvers (Astrometry.net, ASTAP, Online Astrometry). 0062 * If an image is solved successfully, the image central J2000 RA & DE coordinates along with pixel scale, rotation, and partiy are 0063 * reported back. 0064 * Index files management is supported with ability to download astrometry.net files. The user may select and edit different solver 0065 * profiles that provide settings to control both extraction and solving profiles in detail. Manual and automatic field rotation 0066 * is supported in order to align the solved images to a particular orientation in the sky. The manual rotation assistant is an interactive 0067 * tool that helps the user to arrive at the desired framing. 0068 * Align module provide Polar Align Helper tool which enables easy-to-follow polar alignment procedure given wide FOVs (> 1.5 degrees) 0069 * Legacy polar aligment is deprecated. 0070 *@author Jasem Mutlaq 0071 *@version 2.0 0072 */ 0073 class Align : public QWidget, public Ui::Align 0074 { 0075 Q_OBJECT 0076 Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.Ekos.Align") 0077 Q_PROPERTY(Ekos::AlignState status READ status NOTIFY newStatus) 0078 Q_PROPERTY(QStringList logText READ logText NOTIFY newLog) 0079 Q_PROPERTY(QString opticalTrain READ opticalTrain WRITE setOpticalTrain) 0080 Q_PROPERTY(QString camera READ camera) 0081 Q_PROPERTY(QString filterWheel READ filterWheel) 0082 Q_PROPERTY(QString filter READ filter WRITE setFilter) 0083 Q_PROPERTY(double exposure READ exposure WRITE setExposure) 0084 Q_PROPERTY(QList<double> fov READ fov) 0085 Q_PROPERTY(QList<double> cameraInfo READ cameraInfo) 0086 Q_PROPERTY(QList<double> telescopeInfo READ telescopeInfo) 0087 //Q_PROPERTY(QString solverArguments READ solverArguments WRITE setSolverArguments) 0088 0089 public: 0090 explicit Align(const QSharedPointer<ProfileInfo> &activeProfile); 0091 virtual ~Align() override; 0092 0093 typedef enum { GOTO_SYNC, GOTO_SLEW, GOTO_NOTHING } GotoMode; 0094 typedef enum { SOLVER_LOCAL, SOLVER_REMOTE } SolverMode; 0095 typedef enum 0096 { 0097 ALIGN_RESULT_SUCCESS, 0098 ALIGN_RESULT_WARNING, 0099 ALIGN_RESULT_FAILED 0100 } AlignResult; 0101 0102 typedef enum 0103 { 0104 BLIND_IDLE, 0105 BLIND_ENGAGNED, 0106 BLIND_USED 0107 } BlindState; 0108 0109 /** @defgroup AlignDBusInterface Ekos DBus Interface - Align Module 0110 * Ekos::Align interface provides advanced scripting capabilities to solve images using online or offline astrometry.net 0111 */ 0112 0113 /*@{*/ 0114 0115 /** DBUS interface function. 0116 * Select CCD 0117 * @param device CCD device name 0118 * @return Returns true if device if found and selected, false otherwise. 0119 */ 0120 Q_SCRIPTABLE QString camera(); 0121 0122 /** DBUS interface function. 0123 * select the filter device from the available filter drivers. The filter device can be the same as the CCD driver if the filter functionality was embedded within the driver. 0124 * @param device The filter device name 0125 * @return Returns true if filter device is found and set, false otherwise. 0126 */ 0127 Q_SCRIPTABLE QString filterWheel(); 0128 0129 /** DBUS interface function. 0130 * select the filter from the available filters. 0131 * @param filter The filter name 0132 * @return Returns true if filter is found and set, false otherwise. 0133 */ 0134 Q_SCRIPTABLE bool setFilter(const QString &filter); 0135 Q_SCRIPTABLE QString filter(); 0136 0137 /** DBUS interface function. 0138 * Start the plate-solving process given the passed image file. 0139 * @param filename Name of image file to solve. FITS and JPG/JPG/TIFF formats are accepted. 0140 * @param isGenerated Set to true if filename is generated from a CCD capture operation. If the file is loaded from any storage or network media, pass false. 0141 * @return Returns true if device if found and selected, false otherwise. 0142 */ 0143 Q_SCRIPTABLE Q_NOREPLY void startSolving(); 0144 0145 /** DBUS interface function. 0146 * Select Solver Action after successfully solving an image. 0147 * @param mode 0 for Sync, 1 for Slew To Target, 2 for Nothing (just display solution results) 0148 */ 0149 Q_SCRIPTABLE Q_NOREPLY void setSolverAction(int mode); 0150 0151 /** DBUS interface function. 0152 * Returns the solver's solution results 0153 * @return Returns array of doubles. First item is RA in degrees. Second item is DEC in degrees. 0154 */ 0155 Q_SCRIPTABLE QList<double> getSolutionResult(); 0156 0157 /** DBUS interface function. 0158 * Returns the solver's current status 0159 * @return Returns solver status (Ekos::AlignState) 0160 */ 0161 Q_SCRIPTABLE Ekos::AlignState status() 0162 { 0163 return state; 0164 } 0165 0166 /** DBUS interface function. 0167 * @return Returns State of load slew procedure. Idle if not started. Busy if in progress. Ok if complete. Alert if procedure failed. 0168 */ 0169 Q_SCRIPTABLE int getLoadAndSlewStatus() 0170 { 0171 return m_SolveFromFile; 0172 } 0173 0174 /** DBUS interface function. 0175 * Sets the exposure of the selected CCD device. 0176 * @param value Exposure value in seconds 0177 */ 0178 Q_SCRIPTABLE Q_NOREPLY void setExposure(double value); 0179 Q_SCRIPTABLE double exposure() 0180 { 0181 return alignExposure->value(); 0182 } 0183 0184 /** DBUS interface function. 0185 * Get currently active camera info in this order: 0186 * width, height, pixel_size_x, pixel_size_y 0187 */ 0188 Q_SCRIPTABLE QList<double> cameraInfo(); 0189 0190 /** DBUS interface function. 0191 * Get current active telescope info in this order: 0192 * focal length, aperture 0193 */ 0194 Q_SCRIPTABLE QList<double> telescopeInfo(); 0195 0196 /** @}*/ 0197 0198 /** 0199 * @brief Add Camera to the list of available Cameras. 0200 * @param device pointer to camera device. 0201 * @return True if added successfully, false if duplicate or failed to add. 0202 */ 0203 bool setCamera(ISD::Camera *device); 0204 0205 /** 0206 * @brief addFilterWheel Add new filter wheel filter device. 0207 * @param device pointer to filter device. 0208 * @return True if added successfully, false if duplicate or failed to add. 0209 */ 0210 bool setFilterWheel(ISD::FilterWheel *device); 0211 0212 /** 0213 * @brief Add new mount 0214 * @param device pointer to mount device. 0215 * @return True if added successfully, false if duplicate or failed to add. 0216 */ 0217 bool setMount(ISD::Mount *device); 0218 0219 /** 0220 * @brief Add new Dome 0221 * @param device pointer to dome device. 0222 * @return True if added successfully, false if duplicate or failed to add. 0223 */ 0224 bool setDome(ISD::Dome *device); 0225 0226 /** 0227 * @brief Add new Rotator 0228 * @param device pointer to rotator device. 0229 */ 0230 void setRotator(ISD::Rotator *device); 0231 0232 void removeDevice(const QSharedPointer<ISD::GenericDevice> &device); 0233 0234 /** 0235 * @brief setAstrometryDevice 0236 * @param newAstrometry 0237 */ 0238 void setAstrometryDevice(const QSharedPointer<ISD::GenericDevice> &device); 0239 0240 /** 0241 * @brief CCD information is updated, sync them. 0242 */ 0243 void syncCameraInfo(); 0244 0245 /** 0246 * @brief syncCCDControls Update camera controls like gain, offset, ISO..etc. 0247 */ 0248 void syncCameraControls(); 0249 0250 /** 0251 * @brief Generate arguments we pass to the remote solver. 0252 */ 0253 QStringList generateRemoteArgs(const QSharedPointer<FITSData> &imageData); 0254 0255 /** 0256 * @brief Does our parser exist in the system? 0257 */ 0258 bool isParserOK(); 0259 0260 // Log 0261 QStringList logText() 0262 { 0263 return m_LogText; 0264 } 0265 QString getLogText() 0266 { 0267 return m_LogText.join("\n"); 0268 } 0269 void clearLog(); 0270 0271 /** 0272 * @brief getFOVScale Returns calculated FOV values 0273 * @param fov_w FOV width in arcmins 0274 * @param fov_h FOV height in arcmins 0275 * @param fov_scale FOV scale in arcsec per pixel 0276 */ 0277 void getFOVScale(double &fov_w, double &fov_h, double &fov_scale); 0278 QList<double> fov(); 0279 0280 /** 0281 * @brief getCalculatedFOVScale Get calculated FOV scales from the current CCD+Telescope combination. 0282 * @param fov_w return calculated fov width in arcminutes 0283 * @param fov_h return calculated fov height in arcminutes 0284 * @param fov_scale return calculated fov pixcale in arcsecs per pixel. 0285 * @note This is NOT the same as effective FOV which is the measured FOV from astrometry. It is the 0286 * theoretical FOV from calculated values. 0287 */ 0288 void getCalculatedFOVScale(double &fov_w, double &fov_h, double &fov_scale); 0289 0290 void setupFilterManager(); 0291 void setupPlot(); 0292 void setupSolutionTable(); 0293 void setupOptions(); 0294 0295 /** 0296 * @brief Sync the telescope to the solved alignment coordinate. 0297 */ 0298 void Sync(); 0299 0300 /** 0301 * @brief Slew the telescope to the solved alignment coordinate. 0302 */ 0303 void Slew(); 0304 0305 /** 0306 * @brief Sync the telescope to the solved alignment coordinate, and then slew to the target coordinate. 0307 */ 0308 void SlewToTarget(); 0309 0310 /** 0311 * @brief getStellarSolverProfiles 0312 * @return list of StellarSolver profile names 0313 */ 0314 QStringList getStellarSolverProfiles(); 0315 0316 GotoMode currentGOTOMode() const 0317 { 0318 return m_CurrentGotoMode; 0319 } 0320 0321 /** 0322 * @brief generateOptions Generate astrometry.net option given the supplied map 0323 * @param optionsMap List of key=value pairs for all astrometry.net options 0324 * @return String List of valid astrometry.net options 0325 */ 0326 static QStringList generateRemoteOptions(const QVariantMap &optionsMap); 0327 static void generateFOVBounds(double fov_h, QString &fov_low, QString &fov_high, double tolerance = 0.05); 0328 0329 // access to the mount model UI, required for testing 0330 MountModel * mountModel() const 0331 { 0332 return m_MountModel; 0333 } 0334 0335 PolarAlignmentAssistant *polarAlignmentAssistant() const 0336 { 0337 return m_PolarAlignmentAssistant; 0338 } 0339 0340 bool wcsSynced() const 0341 { 0342 return m_wcsSynced; 0343 } 0344 0345 /** 0346 * @brief Process updated device properties 0347 * @param prop INDI Property 0348 */ 0349 void updateProperty(INDI::Property prop); 0350 0351 0352 /** 0353 * @brief Check CCD and make sure information is updated and FOV is re-calculated. 0354 * @param CCDNum By default, we check the already selected CCD in the dropdown menu. If CCDNum is specified, the check is made against this specific CCD in the dropdown menu. CCDNum is the index of the CCD in the dropdown menu. 0355 */ 0356 void checkCamera(); 0357 0358 /** 0359 * @brief Check Filter and make sure information is updated accordingly. 0360 * @param filterNum By default, we check the already selected filter in the dropdown menu. If filterNum is specified, the check is made against this specific filter in the dropdown menu. 0361 * filterNum is the index of the filter in the dropdown menu. 0362 */ 0363 void checkFilter(); 0364 0365 /** 0366 * @brief checkCameraExposureProgress Track the progress of CCD exposure 0367 * @param targetChip Target chip under exposure 0368 * @param remaining how many seconds remaining 0369 * @param state status of exposure 0370 */ 0371 void checkCameraExposureProgress(ISD::CameraChip *targetChip, double remaining, IPState state); 0372 /** 0373 * @brief Process new FITS received from CCD. 0374 * @param bp pointer to blob property 0375 */ 0376 void processData(const QSharedPointer<FITSData> &data); 0377 0378 /** DBUS interface function. 0379 * Loads an image (FITS, RAW, or JPG/PNG) and solve its coordinates, then it slews to the solved coordinates and an image is captured and solved to ensure 0380 * the telescope is pointing to the same coordinates of the image. 0381 * @param image buffer to image data. 0382 * @param extension image extension (e.g. cr2, jpg, fits,..etc). 0383 */ 0384 bool loadAndSlew(const QByteArray &image, const QString &extension); 0385 0386 /** \addtogroup AlignDBusInterface 0387 * @{ 0388 */ 0389 0390 /** 0391 * @brief Stop aligning 0392 * @param mode stop mode (abort or suspend) 0393 */ 0394 void stop(Ekos::AlignState mode); 0395 0396 /** DBUS interface function. 0397 * Aborts the solving operation, handle outside of the align module. 0398 */ 0399 Q_SCRIPTABLE Q_NOREPLY void abort() 0400 { 0401 stop(ALIGN_ABORTED); 0402 } 0403 0404 /** 0405 * @brief Suspend aligning, recovery handled by the align module itself. 0406 */ 0407 void suspend() 0408 { 0409 stop(ALIGN_SUSPENDED); 0410 } 0411 0412 /** DBUS interface function. 0413 * Select the solver mode 0414 * @param type Set solver type. 0 LOCAL, 1 REMOTE (requires remote astrometry driver to be activated) 0415 */ 0416 Q_SCRIPTABLE Q_NOREPLY void setSolverMode(int mode); 0417 0418 /** DBUS interface function. 0419 * Capture and solve an image using the astrometry.net engine 0420 * @return Returns true if the procedure started successful, false otherwise (return true, not false, when retrying!) 0421 */ 0422 Q_SCRIPTABLE bool captureAndSolve(); 0423 0424 /** DBUS interface function. 0425 * Loads an image (FITS, RAW, or JPG/PNG) and solve its coordinates, then it slews to the solved coordinates and an image is captured and solved to ensure 0426 * the telescope is pointing to the same coordinates of the image. 0427 * @param fileURL URL to the image to solve 0428 */ 0429 Q_SCRIPTABLE bool loadAndSlew(QString fileURL = QString()); 0430 0431 /** DBUS interface function. 0432 * Sets the target coordinates that the solver compares the solution coordinates to. 0433 * By default, the target coordinates are those of the current mount when the capture and 0434 * solve operation is started. In case of SYNC, only the error between the solution and target 0435 * coordinates is calculated. When Slew to Target is selected, the mount would be slewed afterwards to 0436 * this target coordinate. 0437 * @param ra0 J2000 Right Ascension in hours. 0438 * @param de0 J2000 Declination in degrees. 0439 */ 0440 Q_SCRIPTABLE Q_NOREPLY void setTargetCoords(double ra0, double de0); 0441 0442 /** 0443 * @brief getTargetCoords QList of target coordinates. 0444 * @return First value is J2000 RA in hours. Second value is J2000 DE in degrees. 0445 */ 0446 Q_SCRIPTABLE QList<double> getTargetCoords(); 0447 0448 0449 /** 0450 * @brief Set the alignment target where the mount is expected to point at. 0451 * @param targetCoord exact coordinates of the target position. 0452 */ 0453 void setTarget(const SkyPoint &targetCoord); 0454 0455 /** 0456 * @brief Set the coordinates that the mount reports as its position 0457 * @param position current mount position 0458 */ 0459 void setTelescopeCoordinates(const SkyPoint &position) 0460 { 0461 m_TelescopeCoord = position; 0462 } 0463 0464 Q_SCRIPTABLE Q_NOREPLY void setTargetPositionAngle(double value); 0465 0466 /** DBUS interface function. 0467 * Sets the binning of the selected CCD device. 0468 * @param binIndex Index of binning value. Default values range from 0 (binning 1x1) to 3 (binning 4x4) 0469 */ 0470 Q_SCRIPTABLE Q_NOREPLY void setBinningIndex(int binIndex); 0471 0472 /** @}*/ 0473 0474 /** 0475 * @brief Solver finished successfully, process the data and execute the required actions depending on the mode. 0476 * @param orientation Orientation of image in degrees (East of North) 0477 * @param ra Center RA in solved image, degrees. 0478 * @param dec Center DEC in solved image, degrees. 0479 * @param pixscale Image scale is arcsec/pixel 0480 * @param eastToTheRight When the image is rotated, so that North is up, East would be to the right. 0481 */ 0482 void solverFinished(double orientation, double ra, double dec, double pixscale, bool eastToTheRight); 0483 0484 void solverComplete(); 0485 0486 /** 0487 * @brief Process solver failure. 0488 */ 0489 void solverFailed(); 0490 0491 /** 0492 * @brief We received new telescope info, process them and update FOV. 0493 */ 0494 bool syncTelescopeInfo(); 0495 0496 void setFocusStatus(Ekos::FocusState state); 0497 0498 // Log 0499 void appendLogText(const QString &); 0500 0501 // Capture 0502 void setCaptureComplete(); 0503 0504 // Update Capture Module status 0505 void setCaptureStatus(Ekos::CaptureState newState); 0506 // Update Mount module status 0507 void setMountStatus(ISD::Mount::Status newState); 0508 0509 void zoomAlignView(); 0510 void setAlignZoom(double scale); 0511 0512 // Manual Rotator Dialog 0513 void toggleManualRotator(bool toggled); 0514 0515 /** 0516 * @brief checkIfRotationRequired Check whether we need to perform an ALIGN_ROTATING action, whether manual or automatic. 0517 * @return True if rotation is required as per the settings, false is not required. 0518 */ 0519 bool checkIfRotationRequired(); 0520 0521 // Settings 0522 QVariantMap getAllSettings() const; 0523 void setAllSettings(const QVariantMap &settings); 0524 0525 // Trains 0526 QString opticalTrain() const 0527 { 0528 return opticalTrainCombo->currentText(); 0529 } 0530 void setOpticalTrain(const QString &value) 0531 { 0532 opticalTrainCombo->setCurrentText(value); 0533 } 0534 0535 Ekos::OpsAlign *getAlignOptionsModule() 0536 { 0537 return opsAlign; 0538 } 0539 0540 private slots: 0541 // Solver timeout 0542 void checkAlignmentTimeout(); 0543 void setAlignTableResult(AlignResult result); 0544 0545 // External View 0546 void showFITSViewer(); 0547 void toggleAlignWidgetFullScreen(); 0548 0549 /** 0550 * @brief prepareCapture Set common settings for capture for align module 0551 * @param targetChip target Chip 0552 */ 0553 void prepareCapture(ISD::CameraChip *targetChip); 0554 0555 //Solutions Display slots 0556 void buildTarget(); 0557 void handlePointTooltip(QMouseEvent *event); 0558 void handleVerticalPlotSizeChange(); 0559 void handleHorizontalPlotSizeChange(); 0560 void selectSolutionTableRow(int row, int column); 0561 void slotClearAllSolutionPoints(); 0562 void slotRemoveSolutionPoint(); 0563 void slotAutoScaleGraph(); 0564 0565 // Model 0566 void slotMountModel(); 0567 0568 // Capture Timeout 0569 void processCaptureTimeout(); 0570 0571 protected slots: 0572 /** 0573 * @brief After a solver process is completed successfully, sync, slew to target, or do nothing as set by the user. 0574 */ 0575 void executeGOTO(); 0576 0577 /** 0578 * @brief refreshAlignOptions is called when settings are updated in OpsAlign. 0579 */ 0580 void refreshAlignOptions(); 0581 0582 void processPAHStage(int stage); 0583 0584 signals: 0585 void newLog(const QString &text); 0586 void newStatus(Ekos::AlignState state); 0587 void newPAAStage(int stage); 0588 void newSolution(const QVariantMap &solution); 0589 0590 // This is sent when we load an image in the view 0591 void newImage(const QSharedPointer<FITSView> &view); 0592 // This is sent when the pixmap is updated within the view 0593 void newFrame(const QSharedPointer<FITSView> &view); 0594 // Send new solver results 0595 void newSolverResults(double orientation, double ra, double dec, double pixscale); 0596 0597 // Train changed 0598 void trainChanged(); 0599 0600 // Settings 0601 void settingsUpdated(const QVariantMap &settings); 0602 0603 // Manual Rotator 0604 void manualRotatorChanged(double currentPA, double targetPA, double pixscale); 0605 0606 private: 0607 0608 void setupOpticalTrainManager(); 0609 void refreshOpticalTrain(); 0610 0611 //////////////////////////////////////////////////////////////////// 0612 /// Settings 0613 //////////////////////////////////////////////////////////////////// 0614 0615 /** 0616 * @brief Connect GUI elements to sync settings once updated. 0617 */ 0618 void connectSettings(); 0619 /** 0620 * @brief Stop updating settings when GUI elements are updated. 0621 */ 0622 void disconnectSettings(); 0623 /** 0624 * @brief loadSettings Load setting from Options and set them accordingly. 0625 */ 0626 void loadGlobalSettings(); 0627 0628 /** 0629 * @brief syncSettings When checkboxes, comboboxes, or spin boxes are updated, save their values in the 0630 * global and per-train settings. 0631 */ 0632 void syncSettings(); 0633 0634 /** 0635 * @brief syncControl Sync setting to widget. The value depends on the widget type. 0636 * @param settings Map of all settings 0637 * @param key name of widget to sync 0638 * @param widget pointer of widget to set 0639 * @return True if sync successful, false otherwise 0640 */ 0641 bool syncControl(const QVariantMap &settings, const QString &key, QWidget * widget); 0642 0643 void setState (AlignState value); 0644 /** 0645 * @brief Retrieve the align status indicator 0646 */ 0647 QProgressIndicator *getProgressStatus(); 0648 0649 /** 0650 * @brief Stop the progress animation in the solution table 0651 */ 0652 void stopProgressAnimation(); 0653 0654 void exportSolutionPoints(); 0655 0656 /** 0657 * @brief Calculate Field of View of CCD+Telescope combination that we need to pass to astrometry.net solver. 0658 */ 0659 void calculateFOV(); 0660 0661 /** 0662 * @brief calculateEffectiveFocalLength Calculate Focal Length purely form astrometric data. 0663 */ 0664 void calculateEffectiveFocalLength(double newFOVW); 0665 0666 /** 0667 * @brief calculateAlignTargetDiff Find the difference between aligned vs. target coordinates and update 0668 * the GUI accordingly. 0669 */ 0670 void calculateAlignTargetDiff(); 0671 0672 /** 0673 * @brief Get formatted RA & DEC coordinates compatible with astrometry.net format. 0674 * @param ra Right ascension 0675 * @param dec Declination 0676 * @param ra_str will contain the formatted RA string 0677 * @param dec_str will contain the formatted DEC string 0678 */ 0679 void getFormattedCoords(double ra, double dec, QString &ra_str, QString &dec_str); 0680 0681 uint8_t getSolverDownsample(uint16_t binnedW); 0682 0683 /** 0684 * @brief setWCSEnabled enables/disables World Coordinate System settings in the CCD driver. 0685 * @param enable true to enable WCS, false to disable. 0686 */ 0687 void setWCSEnabled(bool enable); 0688 0689 void resizeEvent(QResizeEvent *event) override; 0690 0691 KPageWidgetItem *m_IndexFilesPage; 0692 QString savedOptionsProfiles; 0693 0694 /** 0695 * @brief React when a mount motion has been detected 0696 */ 0697 void handleMountMotion(); 0698 0699 /** 0700 * @brief Continue aligning according to the current mount status 0701 */ 0702 void handleMountStatus(); 0703 0704 /** 0705 * @brief initPolarAlignmentAssistant Initialize Polar Alignment Asssistant Tool 0706 */ 0707 void setupPolarAlignmentAssistant(); 0708 0709 void setupRotatorControl(); 0710 0711 /** 0712 * @brief initManualRotator Initialize Manual Rotator Tool 0713 */ 0714 void setupManualRotator(); 0715 0716 /** 0717 * @brief initDarkProcessor Initialize Dark Processor 0718 */ 0719 void setuptDarkProcessor(); 0720 0721 bool matchPAHStage(uint32_t stage); 0722 0723 0724 // Effective FOV 0725 0726 /** 0727 * @brief getEffectiveFOV Search database for effective FOV that matches the current profile and settings 0728 * @return Variant Map containing effect FOV data or empty variant map if none found 0729 */ 0730 QVariantMap getEffectiveFOV(); 0731 void saveNewEffectiveFOV(double newFOVW, double newFOVH); 0732 QList<QVariantMap> effectiveFOVs; 0733 void syncFOV(); 0734 0735 // We are using calculated FOV now until a more accurate effective FOV is found. 0736 bool m_EffectiveFOVPending { false }; 0737 /// Which chip should we invoke in the current CCD? 0738 bool useGuideHead { false }; 0739 /// Can the mount sync its coordinates to those set by Ekos? 0740 bool canSync { false }; 0741 // m_SolveFromFile is true we load an image and solve it, no capture is done. 0742 bool m_SolveFromFile { false }; 0743 // Target Position Angle of solver Load&Slew image to be used for rotator if necessary 0744 double m_TargetPositionAngle { std::numeric_limits<double>::quiet_NaN() }; 0745 // Target Pierside of solver Load&Slew image to be used 0746 ISD::Mount::PierSide m_TargetPierside = ISD::Mount::PIER_UNKNOWN; 0747 double currentRotatorPA { -1 }; 0748 /// Solver iterations count 0749 uint8_t solverIterations { 0 }; 0750 /// Was solving with scale off used? 0751 BlindState useBlindScale {BLIND_IDLE}; 0752 /// Was solving with position off used? 0753 BlindState useBlindPosition {BLIND_IDLE}; 0754 0755 // FOV 0756 double m_CameraPixelWidth { -1 }; 0757 double m_CameraPixelHeight { -1 }; 0758 uint16_t m_CameraWidth { 0 }; 0759 uint16_t m_CameraHeight { 0 }; 0760 0761 double m_FocalLength {-1}; 0762 double m_Aperture {-1}; 0763 double m_FocalRatio {-1}; 0764 double m_Reducer = {-1}; 0765 0766 double m_FOVWidth { 0 }; 0767 double m_FOVHeight { 0 }; 0768 double m_FOVPixelScale { 0 }; 0769 0770 // Keep raw rotator angle 0771 double sRawAngle { INVALID_VALUE }; 0772 // Keep track of solver results 0773 double sOrientation { INVALID_VALUE }; 0774 double sRA { INVALID_VALUE }; 0775 double sDEC { INVALID_VALUE }; 0776 0777 /// Solver alignment coordinates 0778 SkyPoint m_AlignCoord; 0779 /// Target coordinates we need to slew to 0780 SkyPoint m_TargetCoord; 0781 /// Current telescope coordinates 0782 SkyPoint m_TelescopeCoord; 0783 /// Difference between solution and target coordinate 0784 double m_TargetDiffTotal { 1e6 }; 0785 double m_TargetDiffRA { 1e6 }; 0786 double m_TargetDiffDE { 1e6 }; 0787 0788 /// Progress icon if the solver is running 0789 std::unique_ptr<QProgressIndicator> pi; 0790 0791 /// Keep track of how long the solver is running 0792 QElapsedTimer solverTimer; 0793 0794 // The StellarSolver 0795 std::unique_ptr<StellarSolver> m_StellarSolver; 0796 // StellarSolver Profiles 0797 QList<SSolver::Parameters> m_StellarSolverProfiles; 0798 0799 /// Have we slewed? 0800 bool m_wasSlewStarted { false }; 0801 // Above flag only stays false for 10s after slew start. 0802 QElapsedTimer slewStartTimer; 0803 bool didSlewStart(); 0804 // Only wait this many milliseconds for slew to start. 0805 // Otherwise assume it has begun. 0806 static constexpr int MAX_WAIT_FOR_SLEW_START_MSEC = 10000; 0807 0808 // Online and Offline parsers 0809 AstrometryParser* parser { nullptr }; 0810 std::unique_ptr<RemoteAstrometryParser> remoteParser; 0811 QSharedPointer<ISD::GenericDevice> m_RemoteParserDevice; 0812 0813 // Pointers to our devices 0814 ISD::Mount *m_Mount { nullptr }; 0815 ISD::Dome *m_Dome { nullptr }; 0816 ISD::Camera *m_Camera { nullptr }; 0817 ISD::Rotator *m_Rotator { nullptr }; 0818 ISD::FilterWheel *m_FilterWheel { nullptr }; 0819 0820 int currentFilterPosition { -1 }; 0821 /// True if we need to change filter position and wait for result before continuing capture 0822 bool filterPositionPending { false }; 0823 0824 /// Keep track of solver FOV to be plotted in the skymap after each successful solve operation 0825 std::shared_ptr<FOV> solverFOV; 0826 std::shared_ptr<FOV> sensorFOV; 0827 0828 /// WCS 0829 bool m_wcsSynced { false }; 0830 0831 /// Log 0832 QStringList m_LogText; 0833 0834 /// Issue counters 0835 uint8_t m_CaptureTimeoutCounter { 0 }; 0836 uint8_t m_CaptureErrorCounter { 0 }; 0837 uint8_t m_SlewErrorCounter { 0 }; 0838 bool m_resetCaptureTimeoutCounter = false; 0839 0840 QTimer m_CaptureTimer; 0841 0842 // State 0843 AlignState state { ALIGN_IDLE }; 0844 FocusState m_FocusState { FOCUS_IDLE }; 0845 CaptureState m_CaptureState { CAPTURE_IDLE }; 0846 0847 // Track which upload mode the CCD is set to. If set to UPLOAD_LOCAL, then we need to switch it to UPLOAD_CLIENT in order to do focusing, and then switch it back to UPLOAD_LOCAL 0848 ISD::Camera::UploadMode rememberUploadMode { ISD::Camera::UPLOAD_CLIENT }; 0849 0850 GotoMode m_CurrentGotoMode; 0851 0852 QString dirPath; 0853 0854 // Timer 0855 QTimer m_AlignTimer; 0856 0857 // Align Frame 0858 QSharedPointer<AlignView> m_AlignView; 0859 0860 // FITS Viewer in case user want to display in it instead of internal view 0861 QSharedPointer<FITSViewer> fv; 0862 0863 QUrl alignURL; 0864 QUrl alignURLPath; 0865 0866 // keep track of autoWSC 0867 bool rememberAutoWCS { false }; 0868 bool rememberSolverWCS { false }; 0869 0870 // Differential Slewing 0871 bool differentialSlewingActivated { false }; 0872 bool targetAccuracyNotMet { false }; 0873 0874 // Astrometry Options 0875 OpsAstrometry *opsAstrometry { nullptr }; 0876 OpsAlign *opsAlign { nullptr }; 0877 OpsPrograms *opsPrograms { nullptr }; 0878 OpsAstrometryIndexFiles *opsAstrometryIndexFiles { nullptr }; 0879 OpsASTAP *opsASTAP { nullptr }; 0880 StellarSolverProfileEditor *optionsProfileEditor { nullptr }; 0881 0882 // Drawing 0883 QCPCurve *centralTarget { nullptr }; 0884 QCPCurve *yellowTarget { nullptr }; 0885 QCPCurve *redTarget { nullptr }; 0886 QCPCurve *concentricRings { nullptr }; 0887 0888 // Telescope Settings 0889 double m_EffectiveFocalLength = -1; 0890 bool m_isRateSynced = false; 0891 bool domeReady = true; 0892 0893 // CCD Exposure Looping 0894 bool m_RememberCameraFastExposure = { false }; 0895 0896 // Controls 0897 double alignGainSpecialValue {INVALID_VALUE}; 0898 double TargetCustomGainValue {-1}; 0899 0900 // Data 0901 QSharedPointer<FITSData> m_ImageData; 0902 0903 // Active Profile 0904 QSharedPointer<ProfileInfo> m_ActiveProfile; 0905 0906 // Threshold to notify settle time is 3 seconds 0907 static constexpr uint16_t DELAY_THRESHOLD_NOTIFY { 3000 }; 0908 0909 // Mount Model 0910 // N.B. We do not need to use "smart pointer" here as the object memroy 0911 // is taken care of by the Qt framework. 0912 MountModel *m_MountModel {nullptr}; 0913 PolarAlignmentAssistant *m_PolarAlignmentAssistant {nullptr}; 0914 ManualRotator *m_ManualRotator {nullptr}; 0915 0916 // Dark Processor 0917 QPointer<DarkProcessor> m_DarkProcessor; 0918 0919 // Filter Manager 0920 QSharedPointer<FilterManager> m_FilterManager; 0921 0922 // Rotator Control 0923 QSharedPointer<RotatorSettings> m_RotatorControlPanel; 0924 int m_RotatorTimeFrame = 0; 0925 bool m_estimateRotatorTimeFrame = false; 0926 0927 // Settings 0928 QVariantMap m_Settings; 0929 QVariantMap m_GlobalSettings; 0930 0931 bool m_UsedScale = false; 0932 bool m_UsedPosition = false; 0933 double m_ScaleUsed = 0; 0934 double m_RAUsed = 0; 0935 double m_DECUsed = 0; 0936 }; 0937 }