focus.cpp 52.8 KB
Newer Older
Jasem Mutlaq's avatar
Jasem Mutlaq committed
1
2
3
4
5
6
7
8
9
10
11
12
13
/*  Ekos
    Copyright (C) 2012 Jasem Mutlaq <mutlaqja@ikarustech.com>

    This application is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.
 */

#include "focus.h"
#include "Options.h"

#include <KMessageBox>
Jasem Mutlaq's avatar
Jasem Mutlaq committed
14
15
16
17
#include <KLocalizedString>
#include <KPlotting/KPlotWidget>
#include <KPlotting/KPlotObject>
#include <KPlotting/KPlotAxis>
Jasem Mutlaq's avatar
Jasem Mutlaq committed
18

19
20
#include <KNotifications/KNotification>

Jasem Mutlaq's avatar
Jasem Mutlaq committed
21
#include "indi/driverinfo.h"
22
#include "indi/indicommon.h"
23
#include "indi/clientmanager.h"
24
#include "indi/indifilter.h"
Jasem Mutlaq's avatar
Jasem Mutlaq committed
25
26
27

#include "fitsviewer/fitsviewer.h"
#include "fitsviewer/fitstab.h"
Jasem Mutlaq's avatar
Jasem Mutlaq committed
28
#include "fitsviewer/fitsview.h"
Jasem Mutlaq's avatar
Jasem Mutlaq committed
29
30
31
#include "ekosmanager.h"

#include "kstars.h"
32
#include "focusadaptor.h"
Jasem Mutlaq's avatar
Jasem Mutlaq committed
33

34
#include <basedevice.h>
Jasem Mutlaq's avatar
Jasem Mutlaq committed
35

36
37
38
#define MAXIMUM_ABS_ITERATIONS      30
#define MAXIMUM_RESET_ITERATIONS    2
#define DEFAULT_SUBFRAME_DIM        128
39
#define AUTO_STAR_TIMEOUT           45000
40
#define MINIMUM_PULSE_TIMER         32
41
#define MAX_RECAPTURE_RETRIES       3
Jasem Mutlaq's avatar
Jasem Mutlaq committed
42

Jasem Mutlaq's avatar
Jasem Mutlaq committed
43
44
45
46
47
48
49
namespace Ekos
{

Focus::Focus()
{
    setupUi(this);

50
51
52
    new FocusAdaptor(this);
    QDBusConnection::sessionBus().registerObject("/KStars/Ekos/Focus",  this);

Jasem Mutlaq's avatar
Jasem Mutlaq committed
53
54
    currentFocuser = NULL;
    currentCCD     = NULL;
55
56
57
    currentFilter  = NULL;
    filterName     = NULL;
    filterSlot     = NULL;
Jasem Mutlaq's avatar
Jasem Mutlaq committed
58

59
    canAbsMove        = false;
60
    canRelMove        = false;
61
62
63
    inAutoFocus       = false;
    inFocusLoop       = false;
    captureInProgress = false;
64
    inSequenceFocus   = false;
65
    starSelected      = false;
66
    frameModified     = false;
67
    resetFocus        = false;
Jasem Mutlaq's avatar
Jasem Mutlaq committed
68
    m_autoFocusSuccesful = false;
69
    filterPositionPending= false;
70

71
    rememberUploadMode = ISD::CCD::UPLOAD_CLIENT;
72
    HFRInc =0;
73
    noStarCount=0;
74
    reverseDir = false;
75
    initialFocuserAbsPosition = -1;
Jasem Mutlaq's avatar
Jasem Mutlaq committed
76
77
78

    pulseDuration = 1000;

79
    resetFocusIteration=0;
80
    fy=fw=fh=0;
81
    orig_x = orig_y = orig_w = orig_h =-1;
82
    lockedFilterIndex=-1;
Jasem Mutlaq's avatar
Jasem Mutlaq committed
83
    maxHFR=1;
84
    minimumRequiredHFR = -1;
85
    currentFilterIndex=-1;
Jasem Mutlaq's avatar
Jasem Mutlaq committed
86
87
    minPos=1e6;
    maxPos=0;
88

89
    connect(startFocusB, SIGNAL(clicked()), this, SLOT(start()));
90
    connect(stopFocusB, SIGNAL(clicked()), this, SLOT(checkStopFocus()));
Jasem Mutlaq's avatar
Jasem Mutlaq committed
91
92
93
94
95
96
97
98

    connect(focusOutB, SIGNAL(clicked()), this, SLOT(FocusOut()));
    connect(focusInB, SIGNAL(clicked()), this, SLOT(FocusIn()));

    connect(captureB, SIGNAL(clicked()), this, SLOT(capture()));

    connect(AutoModeR, SIGNAL(toggled(bool)), this, SLOT(toggleAutofocus(bool)));

99
    connect(startLoopB, SIGNAL(clicked()), this, SLOT(startFraming()));
100

101
    connect(kcfg_subFrame, SIGNAL(toggled(bool)), this, SLOT(toggleSubframe(bool)));
102

Jasem Mutlaq's avatar
Jasem Mutlaq committed
103
    connect(resetFrameB, SIGNAL(clicked()), this, SLOT(resetFocusFrame()));
104
105
106
107

    connect(CCDCaptureCombo, SIGNAL(activated(QString)), this, SLOT(setDefaultCCD(QString)));
    connect(CCDCaptureCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(checkCCD(int)));

108
    connect(focuserCombo, SIGNAL(activated(int)), this, SLOT(checkFocuser(int)));
109
110
111
    connect(FilterCaptureCombo, SIGNAL(activated(int)), this, SLOT(checkFilter(int)));
    connect(FilterPosCombo, SIGNAL(activated(int)), this, SLOT(updateFilterPos(int)));
    connect(lockFilterCheck, SIGNAL(toggled(bool)), this, SLOT(filterLockToggled(bool)));
112
    connect(filterCombo, SIGNAL(activated(int)), this, SLOT(filterChangeWarning(int)));
113
    connect(setAbsTicksB, SIGNAL(clicked()), this, SLOT(setAbsoluteFocusTicks()));
114
    connect(binningCombo, SIGNAL(activated(int)), this, SLOT(setActiveBinning(int)));
115

116
117
    activeBin=Options::focusXBin();
    binningCombo->setCurrentIndex(activeBin-1);
118

Jasem Mutlaq's avatar
Jasem Mutlaq committed
119
120
    connect(clearDataB, SIGNAL(clicked()) , this, SLOT(clearDataPoints()));

Jasem Mutlaq's avatar
Jasem Mutlaq committed
121
122
    lastFocusDirection = FOCUS_NONE;

123
124
    focusType = FOCUS_MANUAL;

125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
    HFRPlot->setBackground(QBrush(Qt::black));

    HFRPlot->xAxis->setBasePen(QPen(Qt::white, 1));
    HFRPlot->yAxis->setBasePen(QPen(Qt::white, 1));

    HFRPlot->xAxis->setTickPen(QPen(Qt::white, 1));
    HFRPlot->yAxis->setTickPen(QPen(Qt::white, 1));

    HFRPlot->xAxis->setSubTickPen(QPen(Qt::white, 1));
    HFRPlot->yAxis->setSubTickPen(QPen(Qt::white, 1));

    HFRPlot->xAxis->setTickLabelColor(Qt::white);
    HFRPlot->yAxis->setTickLabelColor(Qt::white);

    HFRPlot->xAxis->setLabelColor(Qt::white);
    HFRPlot->yAxis->setLabelColor(Qt::white);

    HFRPlot->xAxis->grid()->setPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine));
    HFRPlot->yAxis->grid()->setPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine));
    HFRPlot->xAxis->grid()->setSubGridPen(QPen(QColor(80, 80, 80), 1, Qt::DotLine));
    HFRPlot->yAxis->grid()->setSubGridPen(QPen(QColor(80, 80, 80), 1, Qt::DotLine));
    HFRPlot->xAxis->grid()->setZeroLinePen(Qt::NoPen);
    HFRPlot->yAxis->grid()->setZeroLinePen(Qt::NoPen);

    HFRPlot->yAxis->setLabel(i18n("HFR"));

    v_graph = HFRPlot->addGraph();
    //v_graph->setBrush(QBrush(QColor(170, 40, 80)));
    //v_graph->setPen(QPen(Qt::red));
    v_graph->setLineStyle(QCPGraph::lsNone);
    v_graph->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, Qt::white, Qt::red, 3));

    //HFRPlot->axis( KPlotWidget::LeftAxis )->setLabel( i18nc("Half Flux Radius", "HFR") );
    //HFRPlot->axis( KPlotWidget::BottomAxis )->setLabel( i18n("Iterations") );
Jasem Mutlaq's avatar
Jasem Mutlaq committed
159

160
161
    //HFRPlot->axis( KPlotWidget::LeftAxis )->setLabel( i18nc("Half Flux Radius", "HFR") );
    //HFRPlot->axis( KPlotWidget::BottomAxis )->setLabel( i18n("Absolute Position") );
162

163
    resetButtons();
Jasem Mutlaq's avatar
Jasem Mutlaq committed
164

165
    appendLogText(i18n("Idle."));
Jasem Mutlaq's avatar
Jasem Mutlaq committed
166

167
168
169
    foreach(QString filter, FITSViewer::filterTypes)
        filterCombo->addItem(filter);

170
171
172
    exposureIN->setValue(Options::focusExposure());
    toleranceIN->setValue(Options::focusTolerance());
    stepIN->setValue(Options::focusTicks());
173
    kcfg_autoSelectStar->setChecked(Options::autoSelectStar());
174
    kcfg_focusBoxSize->setValue(Options::focusBoxSize());    
Jasem Mutlaq's avatar
Jasem Mutlaq committed
175
    maxTravelIN->setValue(Options::focusMaxTravel());
176
    kcfg_subFrame->setChecked(Options::focusSubFrame());
177
    suspendGuideCheck->setChecked(Options::suspendGuiding());
178
    lockFilterCheck->setChecked(Options::lockFocusFilter());
179

Jasem Mutlaq's avatar
Jasem Mutlaq committed
180
181
}

182
183
Focus::~Focus()
{
184
185
    //qDeleteAll(HFRAbsolutePoints);
   // HFRAbsolutePoints.clear();
186
187
}

Jasem Mutlaq's avatar
Jasem Mutlaq committed
188
189
190
void Focus::toggleAutofocus(bool enable)
{
    if (enable)
Jasem Mutlaq's avatar
Jasem Mutlaq committed
191
    {
192
        focusType = FOCUS_AUTO;
Jasem Mutlaq's avatar
Jasem Mutlaq committed
193
194
        drawHFRPlot();
    }
Jasem Mutlaq's avatar
Jasem Mutlaq committed
195
    else
Jasem Mutlaq's avatar
Jasem Mutlaq committed
196
    {
197
        focusType = FOCUS_MANUAL;
Jasem Mutlaq's avatar
Jasem Mutlaq committed
198
199
        drawHFRPlot();
    }
200
201

    if (inFocusLoop || inAutoFocus)
202
        abort();
203
204
    else
        resetButtons();
Jasem Mutlaq's avatar
Jasem Mutlaq committed
205
206
}

207
208
209
210
211
212
void Focus::resetFrame()
{
    if (currentCCD)
    {
        ISD::CCDChip *targetChip = currentCCD->getChip(ISD::CCDChip::PRIMARY_CCD);

213
        if (frameModified && orig_w > 0 && !inAutoFocus && !inFocusLoop && !inSequenceFocus && targetChip && targetChip->canSubframe())
214
        {
215
                    targetChip->setFrame(orig_x, orig_y, orig_w, orig_h);
216
                    frameModified = false;
217
        }
218
219
220
    }
}

Jasem Mutlaq's avatar
Jasem Mutlaq committed
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
void Focus::resetFocusFrame()
{
    if (currentCCD)
    {
        ISD::CCDChip *targetChip = currentCCD->getChip(ISD::CCDChip::PRIMARY_CCD);

        if (targetChip)
        {
            fx=fy=fw=fh=0;
            targetChip->resetFrame();
            targetChip->setFocusFrame(0,0,0,0);
            starSelected = false;
        }
    }
}

Jasem Mutlaq's avatar
Jasem Mutlaq committed
237
bool Focus::setCCD(QString device)
238
239
240
241
{
    for (int i=0; i < CCDCaptureCombo->count(); i++)
        if (device == CCDCaptureCombo->itemText(i))
        {
242
            CCDCaptureCombo->setCurrentIndex(i);
243
244
245
246
247
248
            return true;
        }

    return false;
}

249
250
251
252
253
void Focus::setDefaultCCD(QString ccd)
{
    Options::setDefaultFocusCCD(ccd);
}

254
255
void Focus::checkCCD(int ccdNum)
{
Jasem Mutlaq's avatar
Jasem Mutlaq committed
256
257
258
    if (ccdNum == -1)
        ccdNum = CCDCaptureCombo->currentIndex();

259
    if (ccdNum >=0 && ccdNum <= CCDs.count())
260
    {
261
262
        currentCCD = CCDs.at(ccdNum);

263
264
265
266
267
268
269
270
271
272
273
274
275
276
        ISD::CCDChip *targetChip = currentCCD->getChip(ISD::CCDChip::PRIMARY_CCD);
        if (targetChip)
        {
            binningCombo->setEnabled(targetChip->canBin());
            kcfg_subFrame->setEnabled(targetChip->canSubframe());
            kcfg_autoSelectStar->setEnabled(targetChip->canSubframe());
            if (targetChip->canBin())
            {
                int binx=1,biny=1;
                binningCombo->clear();
                targetChip->getMaxBin(&binx, &biny);
                for (int i=1; i <= binx; i++)
                    binningCombo->addItem(QString("%1x%2").arg(i).arg(i));

277
278
                binningCombo->setCurrentIndex(activeBin-1);

279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
            }

            QStringList isoList = targetChip->getISOList();
            ISOCombo->clear();

            if (isoList.isEmpty())
            {
                ISOCombo->setEnabled(false);
                ISOLabel->setEnabled(false);
            }
            else
            {
                ISOCombo->setEnabled(true);
                ISOLabel->setEnabled(true);
                ISOCombo->addItems(isoList);
                ISOCombo->setCurrentIndex(targetChip->getISOIndex());
            }

        }
    }

Jasem Mutlaq's avatar
Jasem Mutlaq committed
300
301
302
303
304
305
306
307
308
    syncCCDInfo();
}

void Focus::syncCCDInfo()
{

    if (currentCCD == NULL)
        return;

309
    ISD::CCDChip *targetChip = currentCCD->getChip(ISD::CCDChip::PRIMARY_CCD);
310
    if (targetChip)      
311
        targetChip->getFocusFrame(&fx, &fy, &fw, &fh);
312
313
}

314
315
316
317
318
319
320
321
void Focus::addFilter(ISD::GDInterface *newFilter)
{
    foreach(ISD::GDInterface *filter, Filters)
    {
        if (!strcmp(filter->getDeviceName(), newFilter->getDeviceName()))
            return;
    }

322
323
324
325
326
    FilterCaptureLabel->setEnabled(true);
    FilterCaptureCombo->setEnabled(true);
    FilterPosLabel->setEnabled(true);
    FilterPosCombo->setEnabled(true);
    lockFilterCheck->setEnabled(true);
327
328
329
330
331
332
333
334
335
336
337

    FilterCaptureCombo->addItem(newFilter->getDeviceName());

    Filters.append(static_cast<ISD::Filter *>(newFilter));

    checkFilter(0);

    FilterCaptureCombo->setCurrentIndex(0);

}

Jasem Mutlaq's avatar
Jasem Mutlaq committed
338
bool Focus::setFilter(QString device, int filterSlot)
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
{
    bool deviceFound=false;

    for (int i=0; i < FilterCaptureCombo->count(); i++)
        if (device == FilterCaptureCombo->itemText(i))
        {
            checkFilter(i);
            deviceFound = true;
            break;
        }

    if (deviceFound == false)
        return false;

    if (filterSlot < FilterCaptureCombo->count())
        FilterCaptureCombo->setCurrentIndex(filterSlot);

    return true;
}

359
360
361
void Focus::checkFilter(int filterNum)
{
    if (filterNum == -1)
362
    {
363
        filterNum = FilterCaptureCombo->currentIndex();
364
365
366
        if (filterNum == -1)
            return;
    }
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383

    QStringList filterAlias = Options::filterAlias();

    if (filterNum <= Filters.count())
        currentFilter = Filters.at(filterNum);

    FilterPosCombo->clear();

    filterName   = currentFilter->getBaseDevice()->getText("FILTER_NAME");
    filterSlot = currentFilter->getBaseDevice()->getNumber("FILTER_SLOT");

    if (filterSlot == NULL)
    {
        KMessageBox::error(0, i18n("Unable to find FILTER_SLOT property in driver %1", currentFilter->getBaseDevice()->getDeviceName()));
        return;
    }

384
385
    currentFilterIndex = filterSlot->np[0].value - 1;

386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
    for (int i=0; i < filterSlot->np[0].max; i++)
    {
        QString item;

        if (filterName != NULL && (i < filterName->ntp))
            item = filterName->tp[i].text;
        else if (i < filterAlias.count() && filterAlias[i].isEmpty() == false)
            item = filterAlias.at(i);
        else
            item = QString("Filter_%1").arg(i+1);

        FilterPosCombo->addItem(item);

    }

    if (lockFilterCheck->isChecked() == false)
402
        FilterPosCombo->setCurrentIndex( currentFilterIndex);
403
    else
Jasem Mutlaq's avatar
Jasem Mutlaq committed
404
    {
405
406
        if (lockedFilterIndex < 0)
        {
407
408
            //lockedFilterIndex = currentFilterIndex;
            lockedFilterIndex = Options::lockFocusFilterIndex();
409
410
411
412
413
414
415
416
417
418
419
420
421
            emit filterLockUpdated(currentFilter, lockedFilterIndex);
        }
        FilterPosCombo->setCurrentIndex(lockedFilterIndex);
    }

    // If we are waiting to change the filter wheel, let's check if the condition is now met.
    if (filterPositionPending)
    {
        if (lockedFilterIndex == currentFilterIndex)
        {
            filterPositionPending = false;
            capture();
        }
Jasem Mutlaq's avatar
Jasem Mutlaq committed
422
    }
423
424
425
426
427
428

}

void Focus::filterLockToggled(bool enable)
{
    if (enable)
429
430
    {
        lockedFilterIndex = FilterPosCombo->currentIndex();
431
432
        if (lockedFilterIndex >= 0)
            Options::setLockFocusFilterIndex(lockedFilterIndex);
433
434
        emit filterLockUpdated(currentFilter, lockedFilterIndex);
    }
435
    else if (filterSlot != NULL)
436
    {
437
        FilterPosCombo->setCurrentIndex(filterSlot->np[0].value-1);
438
439
        emit filterLockUpdated(NULL, 0);
    }
440
441
442
443
}

void Focus::updateFilterPos(int index)
{
444
    if (lockFilterCheck->isChecked() == true)
445
446
    {
        lockedFilterIndex = index;
447
        Options::setLockFocusFilterIndex(lockedFilterIndex);
448
449
        emit filterLockUpdated(currentFilter, lockedFilterIndex);
    }
450
451
}

452
void Focus::addFocuser(ISD::GDInterface *newFocuser)
Jasem Mutlaq's avatar
Jasem Mutlaq committed
453
{
454
455
456
457
    focuserCombo->addItem(newFocuser->getDeviceName());

    Focusers.append(static_cast<ISD::Focuser*>(newFocuser));

Jasem Mutlaq's avatar
Jasem Mutlaq committed
458
    currentFocuser = static_cast<ISD::Focuser *> (newFocuser);
Jasem Mutlaq's avatar
Jasem Mutlaq committed
459

460
461
462
    checkFocuser();
}

Jasem Mutlaq's avatar
Jasem Mutlaq committed
463
bool Focus::setFocuser(QString device)
464
465
466
467
468
469
470
471
472
473
474
{
    for (int i=0; i < focuserCombo->count(); i++)
        if (device == focuserCombo->itemText(i))
        {
            checkFilter(i);
            return true;
        }

    return false;
}

475
476
477
478
479
480
481
482
void Focus::checkFocuser(int FocuserNum)
{
    if (FocuserNum == -1)
        FocuserNum = focuserCombo->currentIndex();

    if (FocuserNum <= Focusers.count())
        currentFocuser = Focusers.at(FocuserNum);

Jasem Mutlaq's avatar
Jasem Mutlaq committed
483
484
485
486
    if (currentFocuser->canAbsMove())
    {
        canAbsMove = true;
        getAbsFocusPosition();
487
488
489
490
491
492
493
494
495

        absTicksSpin->setEnabled(true);
        setAbsTicksB->setEnabled(true);
    }
    else
    {
        canAbsMove = false;
        absTicksSpin->setEnabled(false);
        setAbsTicksB->setEnabled(false);
Jasem Mutlaq's avatar
Jasem Mutlaq committed
496
497
    }

498
499
500
501
502
503
504
505
506
    if (currentFocuser->canRelMove())
    {
        // We pretend this is an absolute focuser
        canRelMove = true;
        currentPosition = 50000;
        absMotionMax  = 100000;
        absMotionMin  = 0;
    }

507
    connect(currentFocuser, SIGNAL(numberUpdated(INumberVectorProperty*)), this, SLOT(processFocusNumber(INumberVectorProperty*)), Qt::UniqueConnection);
508

509
    AutoModeR->setEnabled(true);
510

511
    resetButtons();
512

513
    if (!inAutoFocus && !inFocusLoop && !captureInProgress && !inSequenceFocus)
514
        emit autoFocusFinished(true, -1);
Jasem Mutlaq's avatar
Jasem Mutlaq committed
515
516
}

517
void Focus::addCCD(ISD::GDInterface *newCCD)
Jasem Mutlaq's avatar
Jasem Mutlaq committed
518
{
519
520
    if (CCDs.contains(static_cast<ISD::CCD *>(newCCD)))
         return;
521

522
    CCDs.append(static_cast<ISD::CCD *>(newCCD));
523

524
    CCDCaptureCombo->addItem(newCCD->getDeviceName());    
525

526
527
    //checkCCD(CCDs.count()-1);
    //CCDCaptureCombo->setCurrentIndex(CCDs.count()-1);
Jasem Mutlaq's avatar
Jasem Mutlaq committed
528
}
Jasem Mutlaq's avatar
Jasem Mutlaq committed
529

Jasem Mutlaq's avatar
Jasem Mutlaq committed
530
531
void Focus::getAbsFocusPosition()
{
532
    INumberVectorProperty *absMove = NULL;
Jasem Mutlaq's avatar
Jasem Mutlaq committed
533
534
    if (canAbsMove)
    {
535
        absMove = currentFocuser->getBaseDevice()->getNumber("ABS_FOCUS_POSITION");
536

Jasem Mutlaq's avatar
Jasem Mutlaq committed
537
538
        if (absMove)
        {
539
           currentPosition = absMove->np[0].value;
Jasem Mutlaq's avatar
Jasem Mutlaq committed
540
541
           absMotionMax  = absMove->np[0].max;
           absMotionMin  = absMove->np[0].min;
542
543
544
545
546
547

           absTicksSpin->setMinimum(absMove->np[0].min);
           absTicksSpin->setMaximum(absMove->np[0].max);
           absTicksSpin->setSingleStep(absMove->np[0].step);

           absTicksSpin->setValue(currentPosition);
Jasem Mutlaq's avatar
Jasem Mutlaq committed
548
549
        }
    }
Jasem Mutlaq's avatar
Jasem Mutlaq committed
550
551
552

}

553
void Focus::start()
Jasem Mutlaq's avatar
Jasem Mutlaq committed
554
{
555
556
557
558
559
560
    if (currentCCD == NULL)
    {
        appendLogText(i18n("No CCD connected."));
        return;
    }

Jasem Mutlaq's avatar
Jasem Mutlaq committed
561
562
    lastFocusDirection = FOCUS_NONE;

563
    lastHFR = 0;
Jasem Mutlaq's avatar
Jasem Mutlaq committed
564
565
566
567
568

    if (canAbsMove)
    {
        absIterations = 0;
        getAbsFocusPosition();
569
        pulseDuration = stepIN->value();
Jasem Mutlaq's avatar
Jasem Mutlaq committed
570
    }
571
572
573
574
575
576
577
578
579
    else if (canRelMove)
    {
        appendLogText(i18n("Setting dummy central position to 50000"));
        absIterations = 0;
        pulseDuration = stepIN->value();
        currentPosition = 50000;
        absMotionMax  = 100000;
        absMotionMin  = 0;
    }
Jasem Mutlaq's avatar
Jasem Mutlaq committed
580
    else
581
582
583
584
585
586
587
588
589
    {
      pulseDuration=stepIN->value();

      if (pulseDuration <= MINIMUM_PULSE_TIMER)
      {
          appendLogText(i18n("Starting pulse step is too low. Increase the step size to %1 or higher...", MINIMUM_PULSE_TIMER*5));
          return;
      }
    }
590

591
    inAutoFocus = true;
Jasem Mutlaq's avatar
Jasem Mutlaq committed
592
    m_autoFocusSuccesful = false;
593

594
    resetButtons();
595
596

    reverseDir = false;
597

598
    /*if (fw > 0 && fh > 0)
599
600
        starSelected= true;
    else
601
        starSelected= false;*/
602

603
    clearDataPoints();
604

605
606
607
    Options::setFocusTicks(stepIN->value());
    Options::setFocusTolerance(toleranceIN->value());
    Options::setFocusExposure(exposureIN->value());
608
    Options::setFocusXBin(activeBin);
Jasem Mutlaq's avatar
Jasem Mutlaq committed
609
    Options::setFocusMaxTravel(maxTravelIN->value());
610

611
    Options::setFocusSubFrame(kcfg_subFrame->isChecked());
612
    Options::setAutoSelectStar(kcfg_autoSelectStar->isChecked());
613
    Options::setSuspendGuiding(suspendGuideCheck->isChecked());
614
    Options::setLockFocusFilter(lockFilterCheck->isChecked());
615

616
617
    if (Options::focusLogging())
        qDebug() << "Focus: Starting focus with pulseDuration " << pulseDuration;
Jasem Mutlaq's avatar
Jasem Mutlaq committed
618

619
    if (kcfg_autoSelectStar->isChecked())
620
        appendLogText(i18n("Autofocus in progress..."));
621
    else
622
        appendLogText(i18n("Please wait until image capture is complete..."));
623

624
625
626
    if (suspendGuideCheck->isChecked())
         emit suspendGuiding(true);

627
628
    emit statusUpdated(true);

629
    capture();
Jasem Mutlaq's avatar
Jasem Mutlaq committed
630
631
}

632
633
634
635
636
void Focus::checkStopFocus()
{
    if (inSequenceFocus == true)
    {
        inSequenceFocus = false;
637
        updateFocusStatus(false);
638
639
    }

640
641
642
643
644
645
    if (captureInProgress && inAutoFocus == false && inFocusLoop == false)
    {
        captureB->setEnabled(true);
        stopFocusB->setEnabled(false);

        appendLogText(i18n("Capture aborted."));
646
647

        emit statusUpdated(false);
648
649
    }

650
    abort();
651
652
}

653
void Focus::abort()
Jasem Mutlaq's avatar
Jasem Mutlaq committed
654
655
{

656
657
    if (Options::focusLogging())
        qDebug() << "Focus: Stopppig Focus";
Jasem Mutlaq's avatar
Jasem Mutlaq committed
658

659
660
    ISD::CCDChip *targetChip = currentCCD->getChip(ISD::CCDChip::PRIMARY_CCD);

661
662
    inAutoFocus = false;
    inFocusLoop = false;
Jasem Mutlaq's avatar
Jasem Mutlaq committed
663
    //starSelected= false;
664
    minimumRequiredHFR    = -1;
665
    noStarCount = 0;
666
    //maxHFR=1;
667

668
669
    disconnect(currentCCD, SIGNAL(BLOBUpdated(IBLOB*)), this, SLOT(newFITS(IBLOB*)));

670
671
    if (rememberUploadMode != currentCCD->getUploadMode())
        currentCCD->setUploadMode(rememberUploadMode);
Jasem Mutlaq's avatar
Jasem Mutlaq committed
672

673
    targetChip->abortExposure();
674
675

    resetFrame();
676
677

    FITSView *targetImage = targetChip->getImage(FITS_FOCUS);
678
679
    if (targetImage)
        targetImage->updateMode(FITS_FOCUS);
680

681
682
    resetButtons();

Jasem Mutlaq's avatar
Jasem Mutlaq committed
683
    absIterations = 0;
684
685
    HFRInc=0;
    reverseDir = false;
Jasem Mutlaq's avatar
Jasem Mutlaq committed
686

687
688
    emit statusUpdated(false);

Jasem Mutlaq's avatar
Jasem Mutlaq committed
689
690
691
692
693
}

void Focus::capture()
{
    if (currentCCD == NULL)
694
695
    {
        appendLogText(i18n("No CCD connected."));
Jasem Mutlaq's avatar
Jasem Mutlaq committed
696
        return;
697
    }
Jasem Mutlaq's avatar
Jasem Mutlaq committed
698

699
700
    ISD::CCDChip *targetChip = currentCCD->getChip(ISD::CCDChip::PRIMARY_CCD);

701
    double seqExpose = exposureIN->value();
702
703
    CCDFrameType ccdFrame = FRAME_LIGHT;

Jasem Mutlaq's avatar
Jasem Mutlaq committed
704
705
    if (currentCCD->isConnected() == false)
    {
706
        appendLogText(i18n("Error: Lost connection to CCD."));
Jasem Mutlaq's avatar
Jasem Mutlaq committed
707
708
709
        return;
    }

710
    if (currentFilter != NULL && lockFilterCheck->isChecked())
711
712
713
714
715
716
717
    {
        if (currentFilter->isConnected() == false)
        {
            appendLogText(i18n("Error: Lost connection to filter wheel."));
            return;
        }

718
719
720
721
        if (lockedFilterIndex != currentFilterIndex)
        {
            int lockedFilterPosition = lockedFilterIndex + 1;
            filterPositionPending = true;
722
            appendLogText(i18n("Changing filter to %1", FilterPosCombo->currentText()));
723
724
725
            currentFilter->runCommand(INDI_SET_FILTER, &lockedFilterPosition);
            return;
        }
726
727
    }

728
729
730
731
732
733
    if (currentCCD->getUploadMode() == ISD::CCD::UPLOAD_LOCAL)
    {
        rememberUploadMode = ISD::CCD::UPLOAD_LOCAL;
        currentCCD->setUploadMode(ISD::CCD::UPLOAD_CLIENT);
    }

734
    targetChip->setBinning(activeBin, activeBin);
735
736
    targetChip->setCaptureMode(FITS_FOCUS);
    targetChip->setCaptureFilter( (FITSScale) filterCombo->currentIndex());
737

738
739
740
    if (ISOCombo->isEnabled() && ISOCombo->currentIndex() != -1 && targetChip->getISOIndex() != ISOCombo->currentIndex())
        targetChip->setISOIndex(ISOCombo->currentIndex());

Jasem Mutlaq's avatar
Jasem Mutlaq committed
741
742
    connect(currentCCD, SIGNAL(BLOBUpdated(IBLOB*)), this, SLOT(newFITS(IBLOB*)));

743
    targetChip->setFrameType(ccdFrame);
744

745
    /*if (subX >= 0 && subY >=0 && subW > 0 && subH > 0)
746
        targetChip->setFrame(subX, subY, subW, subH);
747
748
749
750
751
    else*/
    if (fw == 0 || fh == 0)
        targetChip->getFrame(&fx, &fy, &fw, &fh);

     targetChip->setFrame(fx, fy, fw, fh);
752

753
754
755
     if (fx != orig_x || fy != orig_y || fw != orig_w || fh != orig_h)
         frameModified = true;

756
757
    captureInProgress = true;

758
    targetChip->capture(seqExpose);
Jasem Mutlaq's avatar
Jasem Mutlaq committed
759

760
    if (inFocusLoop == false)
761
    {
762
        appendLogText(i18n("Capturing image..."));
Jasem Mutlaq's avatar
Jasem Mutlaq committed
763

764
765
766
767
768
769
        if (inAutoFocus == false)
        {
            captureB->setEnabled(false);
            stopFocusB->setEnabled(true);
        }
    }
Jasem Mutlaq's avatar
Jasem Mutlaq committed
770
771
772
773
}

void Focus::FocusIn(int ms)
{
774
775
  if (currentFocuser == NULL)
       return;
776

777
778
  if (currentFocuser->isConnected() == false)
  {
779
            appendLogText(i18n("Error: Lost connection to Focuser."));
780
            return;
781
  }
782

783
784
785
    if (ms == -1)
        ms = stepIN->value();

786
787
    if (Options::focusLogging())
        qDebug() << "Focus: Focus in (" << ms << ")" ;
Jasem Mutlaq's avatar
Jasem Mutlaq committed
788

Jasem Mutlaq's avatar
Jasem Mutlaq committed
789
790
    lastFocusDirection = FOCUS_IN;

791
     currentFocuser->focusIn();
792

793
     if (canAbsMove)
794
     {
795
         currentFocuser->moveAbs(currentPosition-ms);
796
797
         appendLogText(i18n("Focusing inward..."));
     }
798
     else if (canRelMove)
799
     {
800
         currentFocuser->moveRel(ms);
801
802
         appendLogText(i18n("Focusing inward..."));
     }
803
     else
804
     {
805
       currentFocuser->moveByTimer(ms);
806
807
808
       appendLogText(i18n("Focusing inward by %1 ms...", ms));
     }

Jasem Mutlaq's avatar
Jasem Mutlaq committed
809
810
811
812
813
814


}

void Focus::FocusOut(int ms)
{
815
816
    if (currentFocuser == NULL)
         return;
817

818
    if (currentFocuser->isConnected() == false)
Jasem Mutlaq's avatar
Jasem Mutlaq committed
819
    {
820
       appendLogText(i18n("Error: Lost connection to Focuser."));
821
       return;
Jasem Mutlaq's avatar
Jasem Mutlaq committed
822
823
824
825
    }

    lastFocusDirection = FOCUS_OUT;

826
827
828
    if (ms == -1)
        ms = stepIN->value();

829
830
    if (Options::focusLogging())
        qDebug() << "Focus: Focus out (" << ms << ")" ;
Jasem Mutlaq's avatar
Jasem Mutlaq committed
831

832
     currentFocuser->focusOut();
Jasem Mutlaq's avatar
Jasem Mutlaq committed
833

834
    if (canAbsMove)
835
    {
836
           currentFocuser->moveAbs(currentPosition+ms);
837
838
           appendLogText(i18n("Focusing outward..."));
    }
839
    else if (canRelMove)
840
    {
841
            currentFocuser->moveRel(ms);
842
843
            appendLogText(i18n("Focusing outward..."));
    }
Jasem Mutlaq's avatar
Jasem Mutlaq committed
844
    else
845
    {
846
            currentFocuser->moveByTimer(ms);
847
848
            appendLogText(i18n("Focusing outward by %1 ms...", ms));
    }
Jasem Mutlaq's avatar
Jasem Mutlaq committed
849
850
851
852
853
}

void Focus::newFITS(IBLOB *bp)
{
    INDI_UNUSED(bp);
854
    QString HFRText;
Jasem Mutlaq's avatar
Jasem Mutlaq committed
855

856
857
858
859
860
    // Ignore guide head if there is any.
    if (!strcmp(bp->name, "CCD2"))
        return;

    ISD::CCDChip *targetChip = currentCCD->getChip(ISD::CCDChip::PRIMARY_CCD);
861
862
863
864

    // Always reset capture mode to NORMAL
    targetChip->setCaptureMode(FITS_NORMAL);

Jasem Mutlaq's avatar
Jasem Mutlaq committed
865
866
    FITSView *targetImage = targetChip->getImage(FITS_FOCUS);

867
868
    if (targetImage == NULL)
    {
869
        appendLogText(i18n("FITS image failed to load, aborting..."));
870
        abort();
871
872
873
        return;
    }

874
875
876
877
    if (captureInProgress && inFocusLoop == false && inAutoFocus==false)
    {
            captureB->setEnabled(true);
            stopFocusB->setEnabled(false);
878
            currentCCD->setUploadMode(rememberUploadMode);
879
880
    }

881
882
    captureInProgress = false;

883
    FITSData *image_data = targetChip->getImageData();
884

885
    disconnect(currentCCD, SIGNAL(BLOBUpdated(IBLOB*)), this, SLOT(newFITS(IBLOB*)));
886

Jasem Mutlaq's avatar
Jasem Mutlaq committed
887
888
889
890
    // If we're not framing, let's try to detect stars
    if (inFocusLoop == false)
    {
        image_data->findStars();
Jasem Mutlaq's avatar
Jasem Mutlaq committed
891

Jasem Mutlaq's avatar
Jasem Mutlaq committed
892
        currentHFR= image_data->getHFR(HFR_MAX);
Jasem Mutlaq's avatar
Jasem Mutlaq committed
893

Jasem Mutlaq's avatar
Jasem Mutlaq committed
894
895
896
897
        if (currentHFR == -1)
        {
            currentHFR = image_data->getHFR();
        }
898

Jasem Mutlaq's avatar
Jasem Mutlaq committed
899
900
        if (Options::focusLogging())
            qDebug() << "Focus newFITS: Current HFR " << currentHFR;
Jasem Mutlaq's avatar
Jasem Mutlaq committed
901

Jasem Mutlaq's avatar
Jasem Mutlaq committed
902
        HFRText = QString("%1").arg(currentHFR, 0,'g', 3);
903

Jasem Mutlaq's avatar
Jasem Mutlaq committed
904
905
        if (focusType == FOCUS_MANUAL && lastHFR == -1)
                appendLogText(i18n("FITS received. No stars detected."));
906

Jasem Mutlaq's avatar
Jasem Mutlaq committed
907
        HFROut->setText(HFRText);
908

Jasem Mutlaq's avatar
Jasem Mutlaq committed
909
910
911
912
        if (currentHFR > 0)
        {
            if (currentHFR > maxHFR)
                maxHFR = currentHFR;
Jasem Mutlaq's avatar
Jasem Mutlaq committed
913

Jasem Mutlaq's avatar
Jasem Mutlaq committed
914
915
916
917
918
            if (hfr_position.empty())
                hfr_position.append(1);
            else
                hfr_position.append(hfr_position.last()+1);
            hfr_value.append(currentHFR);
Jasem Mutlaq's avatar
Jasem Mutlaq committed
919

Jasem Mutlaq's avatar
Jasem Mutlaq committed
920
921
922
            if (focusType == FOCUS_MANUAL || (inAutoFocus && canAbsMove == false && canRelMove == false))
                drawHFRPlot();
        }
Jasem Mutlaq's avatar
Jasem Mutlaq committed
923
    }
Jasem Mutlaq's avatar
Jasem Mutlaq committed
924
925
    // If just framing, let's capture again
    else
926
    {
927
        capture();
928
        return;
Jasem Mutlaq's avatar
Jasem Mutlaq committed
929

930
    }
931

932
933
    if (starSelected == false)
    {
934
        int subBinX=1, subBinY=1;
935
        targetChip->getBinning(&subBinX, &subBinY);
936

Jasem Mutlaq's avatar
Jasem Mutlaq committed
937
        if (kcfg_autoSelectStar->isEnabled() && kcfg_autoSelectStar->isChecked() && focusType == FOCUS_AUTO)
938
939
940
941
        {
            Edge *maxStar = image_data->getMaxHFRStar();
            if (maxStar == NULL)
            {
942
                appendLogText(i18n("Failed to automatically select a star. Please select a star manually."));
943
944
                targetImage->updateMode(FITS_GUIDE);
                targetImage->setGuideBoxSize(kcfg_focusBoxSize->value());
945
946
                if (fw == 0 || fh == 0)
                    targetChip->getFrame(&fx, &fy, &fw, &fh);
947
                targetImage->setGuideSquare(fw/2, fh/2);
948
                connect(targetImage, SIGNAL(guideStarSelected(int,int)), this, SLOT(focusStarSelected(int, int)), Qt::UniqueConnection);
949
950
951

                QTimer::singleShot(AUTO_STAR_TIMEOUT, this, SLOT(checkAutoStarTimeout()));

952
953
954
                return;
            }

955
            if (kcfg_subFrame->isEnabled() && kcfg_subFrame->isChecked())
956
            {
957
                int offset = kcfg_focusBoxSize->value();
958
959
960
961
                int subX=(maxStar->x - offset) * subBinX;
                int subY=(maxStar->y - offset) * subBinY;
                int subW=offset*2*subBinX;
                int subH=offset*2*subBinY;
962

963
964
965
966
967
968
969
970
971
972
973
                int minX, maxX, minY, maxY, minW, maxW, minH, maxH;
                targetChip->getFrameMinMax(&minX, &maxX, &minY, &maxY, &minW, &maxW, &minH, &maxH);

                if (subX< minX)
                    subX=minX;
                if (subY< minY)
                    subY= minY;
                if ((subW+subX)> maxW)
                    subW=maxW-subX;
                if ((subH+subY)> maxH)
                    subH=maxH-subY;
974

975
                targetChip->setFocusFrame(subX, subY, subW, subH);
976

Jasem Mutlaq's avatar
Jasem Mutlaq committed
977
978
                targetChip->getFrame(&orig_x, &orig_y, &orig_w, &orig_h);
                /*orig_x = fx;
979
980
                orig_y = fy;
                orig_w = fw;
Jasem Mutlaq's avatar
Jasem Mutlaq committed
981
                orig_h = fh;*/
982

983
984
985
986
987
                fx += subX;
                fy += subY;
                fw = subW;
                fh = subH;
                frameModified = true;
988
            }
989
990
            else
                targetChip->getFrame(&fx, &fy, &fw, &fh);
991
992
993
994
995
996
<