1 /* 2 SPDX-FileCopyrightText: 2012 Jasem Mutlaq <mutlaqja@ikarustech.com> 3 4 SPDX-License-Identifier: GPL-2.0-or-later 5 */ 6 7 #pragma once 8 9 #include "ui_focus.h" 10 #include "focusprofileplot.h" 11 #include "ekos/ekos.h" 12 #include "ekos/auxiliary/filtermanager.h" 13 #include "ekos/auxiliary/stellarsolverprofileeditor.h" 14 #include "ekos/auxiliary/darkprocessor.h" 15 #include "ekos/mount/mount.h" 16 #include "fitsviewer/fitsviewer.h" 17 #include "indi/indiccd.h" 18 #include "indi/indifocuser.h" 19 #include "indi/indistd.h" 20 #include "indi/indiweather.h" 21 #include "indi/inditelescope.h" 22 23 #include <QtDBus/QtDBus> 24 #include <parameters.h> 25 26 namespace Ekos 27 { 28 29 class FocusAlgorithmInterface; 30 class PolynomialFit; 31 32 /** 33 * @class Focus 34 * @short Supports manual focusing and auto focusing using relative and absolute INDI focusers. 35 * 36 * @author Jasem Mutlaq 37 * @version 1.5 38 */ 39 class Focus : public QWidget, public Ui::Focus 40 { 41 Q_OBJECT 42 Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.Ekos.Focus") 43 Q_PROPERTY(Ekos::FocusState status READ status NOTIFY newStatus) 44 Q_PROPERTY(QStringList logText READ logText NOTIFY newLog) 45 Q_PROPERTY(QString camera READ camera WRITE setCamera) 46 Q_PROPERTY(QString focuser READ focuser WRITE setFocuser) 47 Q_PROPERTY(QString filterWheel READ filterWheel WRITE setFilterWheel) 48 Q_PROPERTY(QString filter READ filter WRITE setFilter) 49 Q_PROPERTY(double HFR READ getHFR NOTIFY newHFR) 50 Q_PROPERTY(double exposure READ exposure WRITE setExposure) 51 52 public: 53 Focus(); 54 ~Focus(); 55 56 typedef enum { FOCUS_NONE, FOCUS_IN, FOCUS_OUT } FocusDirection; 57 typedef enum { FOCUS_MANUAL, FOCUS_AUTO } FocusType; 58 typedef enum { FOCUS_ITERATIVE, FOCUS_POLYNOMIAL, FOCUS_LINEAR } FocusAlgorithm; 59 //typedef enum { FOCUSER_TEMPERATURE, OBSERVATORY_TEMPERATURE, NO_TEMPERATURE } TemperatureSource; 60 61 /** @defgroup FocusDBusInterface Ekos DBus Interface - Focus Module 62 * Ekos::Focus interface provides advanced scripting capabilities to perform manual and automatic focusing operations. 63 */ 64 65 /*@{*/ 66 67 /** DBUS interface function. 68 * select the CCD device from the available CCD drivers. 69 * @param device The CCD device name 70 * @return Returns true if CCD device is found and set, false otherwise. 71 */ 72 Q_SCRIPTABLE bool setCamera(const QString &device); 73 Q_SCRIPTABLE QString camera(); 74 75 /** DBUS interface function. 76 * select the focuser device from the available focuser drivers. The focuser device can be the same as the CCD driver if the focuser functionality was embedded within the driver. 77 * @param device The focuser device name 78 * @return Returns true if focuser device is found and set, false otherwise. 79 */ 80 Q_SCRIPTABLE bool setFocuser(const QString &device); 81 Q_SCRIPTABLE QString focuser(); 82 83 /** DBUS interface function. 84 * 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. 85 * @param device The filter device name 86 * @return Returns true if filter device is found and set, false otherwise. 87 */ 88 Q_SCRIPTABLE bool setFilterWheel(const QString &device); 89 Q_SCRIPTABLE QString filterWheel(); 90 91 /** DBUS interface function. 92 * select the filter from the available filters. 93 * @param filter The filter name 94 * @return Returns true if filter is found and set, false otherwise. 95 */ 96 Q_SCRIPTABLE bool setFilter(const QString &filter); 97 Q_SCRIPTABLE QString filter(); 98 99 /** DBUS interface function. 100 * @return Returns True if current focuser supports auto-focusing 101 */ canAutoFocus()102 Q_SCRIPTABLE bool canAutoFocus() 103 { 104 return (focusType == FOCUS_AUTO); 105 } 106 107 /** DBUS interface function. 108 * @return Returns Half-Flux-Radius in pixels. 109 */ getHFR()110 Q_SCRIPTABLE double getHFR() 111 { 112 return currentHFR; 113 } 114 115 /** DBUS interface function. 116 * Set CCD exposure value 117 * @param value exposure value in seconds. 118 */ 119 Q_SCRIPTABLE Q_NOREPLY void setExposure(double value); exposure()120 Q_SCRIPTABLE double exposure() 121 { 122 return exposureIN->value(); 123 } 124 125 /** DBUS interface function. 126 * Set CCD binning 127 * @param binX horizontal binning 128 * @param binY vertical binning 129 */ 130 Q_SCRIPTABLE Q_NOREPLY void setBinning(int binX, int binY); 131 132 /** DBUS interface function. 133 * Set image filter to apply to the image after capture. 134 * @param value Image filter (Auto Stretch, High Contrast, Equalize, High Pass) 135 */ 136 Q_SCRIPTABLE Q_NOREPLY void setImageFilter(const QString &value); 137 138 /** DBUS interface function. 139 * Set Auto Focus options. The options must be set before starting the autofocus operation. If no options are set, the options loaded from the user configuration are used. 140 * @param enable If true, Ekos will attempt to automatically select the best focus star in the frame. If it fails to select a star, the user will be asked to select a star manually. 141 */ 142 Q_SCRIPTABLE Q_NOREPLY void setAutoStarEnabled(bool enable); 143 144 /** DBUS interface function. 145 * Set Auto Focus options. The options must be set before starting the autofocus operation. If no options are set, the options loaded from the user configuration are used. 146 * @param enable if true, Ekos will capture a subframe around the selected focus star. The subframe size is determined by the boxSize parameter. 147 */ 148 Q_SCRIPTABLE Q_NOREPLY void setAutoSubFrameEnabled(bool enable); 149 150 /** DBUS interface function. 151 * Set Autofocus parameters 152 * @param boxSize the box size around the focus star in pixels. The boxsize is used to subframe around the focus star. 153 * @param stepSize the initial step size to be commanded to the focuser. If the focuser is absolute, the step size is in ticks. For relative focusers, the focuser will be commanded to focus inward for stepSize milliseconds initially. 154 * @param maxTravel the maximum steps permitted before the autofocus operation aborts. 155 * @param tolerance Measure of how accurate the autofocus algorithm is. If the difference between the current HFR and minimum measured HFR is less than %tolerance after the focuser traversed both ends of the V-curve, then the focusing operation 156 * is deemed successful. Otherwise, the focusing operation will continue. 157 */ 158 Q_SCRIPTABLE Q_NOREPLY void setAutoFocusParameters(int boxSize, int stepSize, int maxTravel, double tolerance); 159 160 /** DBUS interface function. 161 * resetFrame Resets the CCD frame to its full native resolution. 162 */ 163 Q_SCRIPTABLE Q_NOREPLY void resetFrame(); 164 165 /** DBUS interface function. 166 * Return state of Focuser module (Ekos::FocusState) 167 */ 168 status()169 Q_SCRIPTABLE Ekos::FocusState status() 170 { 171 return state; 172 } 173 174 /** @}*/ 175 176 /** 177 * @brief Add CCD to the list of available CCD. 178 * @param newCCD pointer to CCD device. 179 */ 180 void addCCD(ISD::GDInterface *newCCD); 181 182 /** 183 * @brief addFocuser Add focuser to the list of available focusers. 184 * @param newFocuser pointer to focuser device. 185 */ 186 void addFocuser(ISD::GDInterface *newFocuser); 187 188 /** 189 * @brief addFilter Add filter to the list of available filters. 190 * @param newFilter pointer to filter device. 191 */ 192 void addFilter(ISD::GDInterface *newFilter); 193 194 195 /** 196 * @brief addTemperatureSource Add temperature source to the list of available sources. 197 * @param newSource Device with temperature reporting capability 198 */ 199 void addTemperatureSource(ISD::GDInterface *newSource); 200 201 /** 202 * @brief removeDevice Remove device from Focus module 203 * @param deviceRemoved pointer to device 204 */ 205 void removeDevice(ISD::GDInterface *deviceRemoved); 206 207 void setFilterManager(const QSharedPointer<FilterManager> &manager); 208 209 void clearLog(); logText()210 QStringList logText() 211 { 212 return m_LogText; 213 } getLogText()214 QString getLogText() 215 { 216 return m_LogText.join("\n"); 217 } 218 219 // Presets 220 QJsonObject getSettings() const; 221 void setSettings(const QJsonObject &settings); 222 // Primary Settings 223 QJsonObject getPrimarySettings() const; 224 void setPrimarySettings(const QJsonObject &settings); 225 // Process Settings 226 QJsonObject getProcessSettings() const; 227 void setProcessSettings(const QJsonObject &settings); 228 // Mechanics Settings 229 QJsonObject getMechanicsSettings() const; 230 void setMechanicsSettings(const QJsonObject &settings); 231 232 public slots: 233 234 /** \addtogroup FocusDBusInterface 235 * @{ 236 */ 237 238 /* Focus */ 239 /** DBUS interface function. 240 * Start the autofocus operation. 241 */ 242 Q_SCRIPTABLE Q_NOREPLY void start(); 243 244 /** DBUS interface function. 245 * Abort the autofocus operation. 246 */ 247 Q_SCRIPTABLE Q_NOREPLY void abort(); 248 249 /** DBUS interface function. 250 * Capture a focus frame. 251 * @param settleTime if > 0 wait for the given time in seconds before starting to capture 252 */ 253 Q_SCRIPTABLE Q_NOREPLY void capture(double settleTime = 0.0); 254 255 /** DBUS interface function. 256 * Focus inward 257 * @param ms If set, focus inward for ms ticks (Absolute Focuser), or ms milliseconds (Relative Focuser). If not set, it will use the value specified in the options. 258 */ 259 Q_SCRIPTABLE bool focusIn(int ms = -1); 260 261 /** DBUS interface function. 262 * Focus outward 263 * @param ms If set, focus outward for ms ticks (Absolute Focuser), or ms milliseconds (Relative Focuser). If not set, it will use the value specified in the options. 264 */ 265 Q_SCRIPTABLE bool focusOut(int ms = -1); 266 267 /** @}*/ 268 269 /** 270 * @brief startFraming Begins continuous capture of the CCD and calculates HFR every frame. 271 */ 272 void startFraming(); 273 274 /** 275 * @brief Move the focuser to the initial focus position. 276 */ 277 void resetFocuser(); 278 279 /** 280 * @brief checkStopFocus Perform checks before stopping the autofocus operation. Some checks are necessary for in-sequence focusing. 281 * @param abort true iff focusing should be aborted, false if it should only be stopped and marked as failed 282 */ 283 void checkStopFocus(bool abort); 284 285 /** 286 * @brief React when a meridian flip has been started 287 */ 288 void meridianFlipStarted(); 289 290 /** 291 * @brief Check CCD and make sure information is updated accordingly. This simply calls syncCCDInfo for the current CCD. 292 * @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. 293 * CCDNum is the index of the CCD in the dropdown menu. 294 */ 295 void checkCCD(int CCDNum = -1); 296 297 /** 298 * @brief syncCCDInfo Read current CCD information and update settings accordingly. 299 */ 300 void syncCCDInfo(); 301 302 /** 303 * @brief Check Focuser and make sure information is updated accordingly. 304 * @param FocuserNum By default, we check the already selected focuser in the dropdown menu. If FocuserNum is specified, the check is made against this specific focuser in the dropdown menu. 305 * FocuserNum is the index of the focuser in the dropdown menu. 306 */ 307 void checkFocuser(int FocuserNum = -1); 308 309 /** 310 * @brief Check Filter and make sure information is updated accordingly. 311 * @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. 312 * filterNum is the index of the filter in the dropdown menu. 313 */ 314 void checkFilter(int filterNum = -1); 315 316 /** 317 * @brief Check temperature source and make sure information is updated accordingly. 318 * @param index Index of source in combo box. If -1, then use the currently selected source. 319 */ 320 void checkTemperatureSource(int index = -1); 321 322 /** 323 * @brief clearDataPoints Remove all data points from HFR plots 324 */ 325 void clearDataPoints(); 326 327 /** 328 * @brief focusStarSelected The user selected a focus star, save its coordinates and subframe it if subframing is enabled. 329 * @param x X coordinate 330 * @param y Y coordinate 331 */ 332 void focusStarSelected(int x, int y); 333 334 /** 335 * @brief selectFocusStarFraction Select the focus star based by fraction of the overall size. 336 * It calls focusStarSelected after multiplying the fractions (0.0 to 1.0) with the focus view width and height. 337 * @param x final x = x * focusview_width 338 * @param y final y = y * focusview_height 339 */ 340 void selectFocusStarFraction(double x, double y); 341 342 /** 343 * @brief newFITS A new FITS blob is received by the CCD driver. 344 * @param bp pointer to blob data 345 */ 346 void processData(const QSharedPointer<FITSData> &data); 347 348 /** 349 * @brief processFocusNumber Read focus number properties of interest as they arrive from the focuser driver and process them accordingly. 350 * @param nvp pointer to updated focuser number property. 351 */ 352 void processFocusNumber(INumberVectorProperty *nvp); 353 354 /** 355 * @brief processTemperatureSource Updates focus temperature source. 356 * @param nvp pointer to updated focuser number property. 357 */ 358 void processTemperatureSource(INumberVectorProperty *nvp); 359 360 /** 361 * @brief checkFocus Given the minimum required HFR, check focus and calculate HFR. If current HFR exceeds required HFR, start autofocus process, otherwise do nothing. 362 * @param requiredHFR Minimum HFR to trigger autofocus process. 363 */ 364 void checkFocus(double requiredHFR); 365 366 /** 367 * @brief setFocusStatus Upon completion of the focusing process, set its status (fail or pass) and reset focus process to clean state. 368 * @param status If true, the focus process finished successfully. Otherwise, it failed. 369 */ 370 //void setAutoFocusResult(bool status); 371 372 /** 373 * @brief filterChangeWarning Warn the user it is not a good idea to apply image filter in the filter process as they can skew the HFR calculations. 374 * @param index Index of image filter selected by the user. 375 */ 376 void filterChangeWarning(int index); 377 378 // Logging methods - one for INFO messages to the kstars log, and one for a CSV auto-focus log 379 void appendLogText(const QString &); 380 void appendFocusLogText(const QString &); 381 382 // Adjust focuser offset, relative or absolute 383 void adjustFocusOffset(int value, bool useAbsoluteOffset); 384 385 // Update Mount module status 386 void setMountStatus(ISD::Telescope::Status newState); 387 388 // Update Altitude From Mount 389 void setMountCoords(const SkyPoint &position, ISD::Telescope::PierSide pierSide, const dms &ha); 390 391 /** 392 * @brief toggleVideo Turn on and off video streaming if supported by the camera. 393 * @param enabled Set to true to start video streaming, false to stop it if active. 394 */ 395 void toggleVideo(bool enabled); 396 397 /** 398 * @brief setWeatherData Updates weather data that could be used to extract focus temperature from observatory 399 * in case focus native temperature is not available. 400 */ 401 //void setWeatherData(const std::vector<ISD::Weather::WeatherData> &data); 402 403 /** 404 * @brief loadOptionsProfiles Load StellarSolver Profile 405 */ 406 void loadStellarSolverProfiles(); 407 408 /** 409 * @brief getStellarSolverProfiles 410 * @return list of StellarSolver profile names 411 */ 412 QStringList getStellarSolverProfiles(); 413 414 415 416 protected: 417 void addPlotPosition(int pos, double hfr, bool plot = true); 418 419 private slots: 420 /** 421 * @brief toggleSubframe Process enabling and disabling subfrag. 422 * @param enable If true, subframing is enabled. If false, subframing is disabled. Even if subframing is enabled, it must be supported by the CCD driver. 423 */ 424 void toggleSubframe(bool enable); 425 426 void checkAutoStarTimeout(); 427 428 void setAbsoluteFocusTicks(); 429 430 void updateBoxSize(int value); 431 432 void processCaptureTimeout(); 433 434 void processCaptureError(ISD::CCD::ErrorType type); 435 436 void setCaptureComplete(); 437 438 void showFITSViewer(); 439 440 void toggleFocusingWidgetFullScreen(); 441 442 void setVideoStreamEnabled(bool enabled); 443 444 void syncSettings(); 445 446 void calculateHFR(); 447 void setCurrentHFR(double value); 448 449 signals: 450 void newLog(const QString &text); 451 void newStatus(Ekos::FocusState state); 452 void newHFR(double hfr, int position); 453 void newFocusTemperatureDelta(double delta, double absTemperature); 454 455 void absolutePositionChanged(int value); 456 void focusPositionAdjusted(); 457 458 void suspendGuiding(); 459 void resumeGuiding(); 460 void newImage(FITSView *view); 461 void newStarPixmap(QPixmap &); 462 void settingsUpdated(const QJsonObject &settings); 463 464 // Signals for Analyze. 465 void autofocusStarting(double temperature, const QString &filter); 466 void autofocusComplete(const QString &filter, const QString &points); 467 void autofocusAborted(const QString &filter, const QString &points); 468 469 // HFR V curve plot events 470 /** 471 * @brief initialize the HFR V plot 472 * @param showPosition show focuser position (true) or count focus iterations (false) 473 */ 474 void initHFRPlot(bool showPosition); 475 476 /** 477 * @brief new HFR plot position 478 * @param pos focuser position 479 * @param hfr measured star HFR value 480 * @param pulseDuration Pulse duration in ms for relative focusers that only support timers, 481 * or the number of ticks in a relative or absolute focuser 482 * */ 483 void newHFRPlotPosition(double pos, double hfr, int pulseDuration, bool plot = true); 484 485 /** 486 * @brief draw the approximating polynomial into the HFR V-graph 487 * @param poly pointer to the polynomial approximation 488 * @param isVShape has the solution a V shape? 489 * @param activate make the graph visible? 490 */ 491 void drawPolynomial(PolynomialFit *poly, bool isVShape, bool activate, bool plot = true); 492 493 /** 494 * @brief Focus solution with minimal HFR found 495 * @param solutionPosition focuser position 496 * @param solutionValue HFR value 497 */ 498 void minimumFound(double solutionPosition, double solutionValue, bool plot = true); 499 500 /** 501 * @brief redraw the entire HFR plot 502 * @param poly pointer to the polynomial approximation 503 * @param solutionPosition solution focuser position 504 * @param solutionValue solution HFR value 505 */ 506 void redrawHFRPlot(PolynomialFit *poly, double solutionPosition, double solutionValue); 507 508 /** 509 * @brief draw a title on the focus plot 510 * @param title the title 511 */ 512 void setTitle(const QString &title, bool plot = true); 513 514 private: 515 516 QList<SSolver::Parameters> m_StellarSolverProfiles; 517 QString savedOptionsProfiles; 518 StellarSolverProfileEditor *optionsProfileEditor { nullptr }; 519 520 //////////////////////////////////////////////////////////////////// 521 /// Connections 522 //////////////////////////////////////////////////////////////////// 523 void initConnections(); 524 525 //////////////////////////////////////////////////////////////////// 526 /// Settings 527 //////////////////////////////////////////////////////////////////// 528 529 /** 530 * @brief initSettings Connect settings to slots to update the value when changed 531 */ 532 void initSettingsConnections(); 533 /** 534 * @brief loadSettings Load setting from Options and set them accordingly. 535 */ 536 void loadSettings(); 537 538 //////////////////////////////////////////////////////////////////// 539 /// HFR Plot 540 //////////////////////////////////////////////////////////////////// 541 void initPlots(); 542 543 //////////////////////////////////////////////////////////////////// 544 /// Positions 545 //////////////////////////////////////////////////////////////////// 546 void getAbsFocusPosition(); 547 bool autoFocusChecks(); 548 void autoFocusAbs(); 549 void autoFocusLinear(); 550 void autoFocusRel(); 551 552 // Linear does plotting differently from the rest. 553 void plotLinearFocus(); 554 555 /** @brief Helper function determining whether the focuser behaves like a position 556 * based one (vs. a timer based) 557 */ isPositionBased()558 bool isPositionBased() 559 { 560 return (canAbsMove || canRelMove || (focusAlgorithm == FOCUS_LINEAR)); 561 } 562 void resetButtons(); 563 void stop(FocusState completionState = FOCUS_ABORTED); 564 565 void initView(); 566 567 /** 568 * @brief prepareCapture Set common settings for capture for focus module 569 * @param targetChip target Chip 570 */ 571 void prepareCapture(ISD::CCDChip *targetChip); 572 //////////////////////////////////////////////////////////////////// 573 /// HFR 574 //////////////////////////////////////////////////////////////////// 575 void setHFRComplete(); 576 577 // Sets the algorithm and enables/disables various UI inputs. 578 void setFocusAlgorithm(FocusAlgorithm algorithm); 579 580 // Move the focuser in (negative) or out (positive amount). 581 bool changeFocus(int amount); 582 583 // Start up capture, or occasionally move focuser again, after current focus-move accomplished. 584 void autoFocusProcessPositionChange(IPState state); 585 586 // For the Linear algorithm, which always scans in (from higher position to lower position) 587 // if we notice the new position is higher than the current position (that is, it is the start 588 // of a new scan), we adjust the new position to be several steps further out than requested 589 // and set focuserAdditionalMovement to the extra motion, so that after this motion completes 590 // we will then scan back in (back to the originally requested position). This "dance" is done 591 // to reduce backlash on such movement changes and so that we've always focused in before capture. 592 int adjustLinearPosition(int position, int newPosition); 593 594 /** 595 * @brief syncTrackingBoxPosition Sync the tracking box to the current selected star center 596 */ 597 void syncTrackingBoxPosition(); 598 599 /** @internal Search for stars using the method currently configured, and return the consolidated HFR. 600 * @param image_data is the FITS frame to work with. 601 * @return the HFR of the star or field of stars in the frame, depending on the consolidation method, or -1 if it cannot be estimated. 602 */ 603 void analyzeSources(); 604 605 /** @internal Add a new HFR for the current focuser position. 606 * @param newHFR is the new HFR to consider for the current focuser position. 607 * @return true if a new sample is required, else false. 608 */ 609 bool appendHFR(double newHFR); 610 611 612 /** 613 * @brief completeAutofocusProcedure finishes off autofocus and emits a message for other modules. 614 */ 615 void completeFocusProcedure(FocusState completionState, bool plot = true); 616 617 /** 618 * @brief activities to be executed after the configured settling time 619 * @param completionState state the focuser completed with 620 * @param autoFocusUsed is autofocus running? 621 */ 622 void settle(const FocusState completionState, const bool autoFocusUsed); 623 624 // void initializeFocuserTemperature(); 625 void setLastFocusTemperature(); 626 bool findTemperatureElement(ISD::GDInterface *device); 627 // void updateTemperature(TemperatureSource source, double newTemperature); 628 // void emitTemperatureEvents(TemperatureSource source, double newTemperature); 629 630 bool syncControl(const QJsonObject &settings, const QString &key, QWidget * widget); 631 632 /** 633 * @brief handleFocusMotionTimeout When focuser is command to go to a target position, we expect to receive a notification 634 * that it arrived at the desired destination. If not, we command it again. 635 */ 636 void handleFocusMotionTimeout(); 637 638 /// Focuser device needed for focus operation 639 ISD::Focuser *currentFocuser { nullptr }; 640 /// CCD device needed for focus operation 641 ISD::CCD *currentCCD { nullptr }; 642 /// Optional device filter 643 ISD::GDInterface *currentFilter { nullptr }; 644 /// Optional temperature source element 645 INumber *currentTemperatureSourceElement {nullptr}; 646 647 /// Current filter position 648 int currentFilterPosition { -1 }; 649 int fallbackFilterPosition { -1 }; 650 /// True if we need to change filter position and wait for result before continuing capture 651 bool filterPositionPending { false }; 652 bool fallbackFilterPending { false }; 653 654 /// List of Focusers 655 QList<ISD::Focuser *> Focusers; 656 /// List of CCDs 657 QList<ISD::CCD *> CCDs; 658 /// They're generic GDInterface because they could be either ISD::CCD or ISD::Filter 659 QList<ISD::GDInterface *> Filters; 660 /// They're generic GDInterface because they could be either ISD::CCD or ISD::Filter or ISD::Weather 661 QList<ISD::GDInterface *> TemperatureSources; 662 663 /// As the name implies 664 FocusDirection m_LastFocusDirection { FOCUS_NONE }; 665 /// Keep track of the last requested steps 666 uint32_t m_LastFocusSteps {0}; 667 /// What type of focusing are we doing right now? 668 FocusType focusType { FOCUS_MANUAL }; 669 /// Focus HFR & Centeroid algorithms 670 StarAlgorithm focusDetection { ALGORITHM_GRADIENT }; 671 /// Focus Process Algorithm 672 FocusAlgorithm focusAlgorithm { FOCUS_ITERATIVE }; 673 674 /********************* 675 * HFR Club variables 676 *********************/ 677 678 /// Current HFR value just fetched from FITS file 679 double currentHFR { 0 }; 680 /// Last HFR value recorded 681 double lastHFR { 0 }; 682 /// If (currentHFR > deltaHFR) we start the autofocus process. 683 double minimumRequiredHFR { -1 }; 684 /// Maximum HFR recorded 685 double maxHFR { 1 }; 686 /// Is HFR increasing? We're going away from the sweet spot! If HFRInc=1, we re-capture just to make sure HFR calculations are correct, if HFRInc > 1, we switch directions 687 int HFRInc { 0 }; 688 /// If HFR decreasing? Well, good job. Once HFR start decreasing, we can start calculating HFR slope and estimating our next move. 689 int HFRDec { 0 }; 690 691 /**************************** 692 * Absolute position focusers 693 ****************************/ 694 /// Absolute focus position 695 int currentPosition { 0 }; 696 /// Motion state of the absolute focuser 697 IPState currentPositionState {IPS_IDLE}; 698 /// What was our position before we started the focus process? 699 int initialFocuserAbsPosition { -1 }; 700 /// Pulse duration in ms for relative focusers that only support timers, or the number of ticks in a relative or absolute focuser 701 int pulseDuration { 1000 }; 702 /// Does the focuser support absolute motion? 703 bool canAbsMove { false }; 704 /// Does the focuser support relative motion? 705 bool canRelMove { false }; 706 /// Does the focuser support timer-based motion? 707 bool canTimerMove { false }; 708 /// Maximum range of motion for our lovely absolute focuser 709 double absMotionMax { 0 }; 710 /// Minimum range of motion for our lovely absolute focuser 711 double absMotionMin { 0 }; 712 /// How many iterations have we completed now in our absolute autofocus algorithm? We can't go forever 713 int absIterations { 0 }; 714 715 /**************************** 716 * Misc. variables 717 ****************************/ 718 719 /// Are we in the process of capturing an image? 720 bool captureInProgress { false }; 721 /// Are we in the process of calculating HFR? 722 bool hfrInProgress { false }; 723 // Was the frame modified by us? Better keep track since we need to return it to its previous state once we are done with the focus operation. 724 //bool frameModified; 725 /// Was the modified frame subFramed? 726 bool subFramed { false }; 727 /// If the autofocus process fails, let's not ruin the capture session probably taking place in the next tab. Instead, we should restart it and try again, but we keep count until we hit MAXIMUM_RESET_ITERATIONS 728 /// and then we truly give up. 729 int resetFocusIteration { 0 }; 730 /// Which filter must we use once the autofocus process kicks in? 731 int lockedFilterIndex { -1 }; 732 /// Keep track of what we're doing right now 733 bool inAutoFocus { false }; 734 bool inFocusLoop { false }; 735 //bool inSequenceFocus { false }; 736 bool restartFocus { false }; 737 /// Did we reverse direction? 738 bool reverseDir { false }; 739 /// Did the user or the auto selection process finish selecting our focus star? 740 bool starSelected { false }; 741 /// Adjust the focus position to a target value 742 bool adjustFocus { false }; 743 // Target frame dimensions 744 //int fx,fy,fw,fh; 745 /// If HFR=-1 which means no stars detected, we need to decide how many times should the re-capture process take place before we give up or reverse direction. 746 int noStarCount { 0 }; 747 /// 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 748 ISD::CCD::UploadMode rememberUploadMode { ISD::CCD::UPLOAD_CLIENT }; 749 /// Previous binning setting 750 int activeBin { 0 }; 751 /// HFR values for captured frames before averages 752 QVector<double> HFRFrames; 753 // Camera Fast Exposure 754 bool m_RememberCameraFastExposure = { false }; 755 // Future Watch 756 QFutureWatcher<bool> m_StarFinderWatcher; 757 758 /// Autofocus log file info. 759 QStringList m_LogText; 760 QFile m_FocusLogFile; 761 QString m_FocusLogFileName; 762 bool m_FocusLogEnabled { false }; 763 764 ITextVectorProperty *filterName { nullptr }; 765 INumberVectorProperty *filterSlot { nullptr }; 766 767 /**************************** 768 * Plot variables 769 ****************************/ 770 771 /// Plot minimum positions 772 double minPos { 1e6 }; 773 /// Plot maximum positions 774 double maxPos { 0 }; 775 776 /// HFR V curve plot points 777 QVector<double> hfr_position, hfr_value; 778 bool isVShapeSolution = false; 779 780 /// State 781 Ekos::FocusState state { Ekos::FOCUS_IDLE }; 782 783 /// FITS Scale 784 FITSScale defaultScale; 785 786 /// CCD Chip frame settings 787 QMap<ISD::CCDChip *, QVariantMap> frameSettings; 788 789 /// Selected star coordinates 790 QVector3D starCenter; 791 792 // Remember last star center coordinates in case of timeout in manual select mode 793 QVector3D rememberStarCenter; 794 795 /// Focus Frame 796 FITSView *focusView { nullptr }; 797 798 /// Star Select Timer 799 QTimer waitStarSelectTimer; 800 801 /// FITS Viewer in case user want to display in it instead of internal view 802 QPointer<FITSViewer> fv; 803 804 /// Track star position and HFR to know if we're detecting bogus stars due to detection algorithm false positive results 805 QVector<QVector3D> starsHFR; 806 807 /// Relative Profile 808 FocusProfilePlot *profilePlot { nullptr }; 809 QDialog *profileDialog { nullptr }; 810 811 /// Polynomial fitting. 812 std::unique_ptr<PolynomialFit> polynomialFit; 813 int polySolutionFound { 0 }; 814 815 // Capture timers 816 QTimer captureTimer; 817 QTimer captureTimeout; 818 uint8_t captureTimeoutCounter { 0 }; 819 uint8_t captureFailureCounter { 0 }; 820 821 // Focus motion timer. 822 QTimer m_FocusMotionTimer; 823 uint8_t m_FocusMotionTimerCounter {0}; 824 825 // Guide Suspend 826 bool m_GuidingSuspended { false }; 827 828 // Filter Manager 829 QSharedPointer<FilterManager> filterManager; 830 831 // Data 832 QSharedPointer<FITSData> m_ImageData; 833 834 // Linear focuser. 835 std::unique_ptr<FocusAlgorithmInterface> linearFocuser; 836 int focuserAdditionalMovement { 0 }; 837 int linearRequestedPosition { 0 }; 838 839 bool hasDeviation { false }; 840 841 //double observatoryTemperature { INVALID_VALUE }; 842 double m_LastSourceAutofocusTemperature { INVALID_VALUE }; 843 //TemperatureSource lastFocusTemperatureSource { NO_TEMPERATURE }; 844 845 // Mount altitude value for logging 846 double mountAlt { INVALID_VALUE }; 847 848 // Dark Processor 849 QPointer<DarkProcessor> m_DarkProcessor; 850 }; 851 } 852