void Focus::processFocusProperties(INumberVectorProperty *nvp) { if (!strcmp(nvp->name, "ABS_FOCUS_POSITION")) { INumber *pos = IUFindNumber(nvp, "FOCUS_ABSOLUTE_POSITION"); if (pos) pulseStep = pos->value; if (canAbsMove && inAutoFocus) { if (nvp->s == IPS_OK) capture(); else if (nvp->s == IPS_ALERT) { appendLogText(i18n("Focuser error, check INDI panel.")); stopFocus(); } } return; } if (!strcmp(nvp->name, "FOCUS_TIMER")) { if (canAbsMove == false && inAutoFocus) { if (nvp->s == IPS_OK) capture(); else if (nvp->s == IPS_ALERT) { appendLogText(i18n("Focuser error, check INDI panel.")); stopFocus(); } } return; } }
void Focus::toggleAutofocus(bool enable) { if (enable) focusType = FOCUS_AUTO; else focusType = FOCUS_MANUAL; if (inFocusLoop || inAutoFocus) stopFocus(); else resetButtons(); }
Focus::Focus() { setupUi(this); currentFocuser = NULL; currentCCD = NULL; canAbsMove = false; inAutoFocus = false; inFocusLoop = false; HFRInc =0; reverseDir = false; pulseDuration = 1000; connect(startFocusB, SIGNAL(clicked()), this, SLOT(startFocus())); connect(stopFocusB, SIGNAL(clicked()), this, SLOT(stopFocus())); 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))); connect(startLoopB, SIGNAL(clicked()), this, SLOT(startLooping())); connect(CCDCaptureCombo, SIGNAL(activated(int)), this, SLOT(checkCCD(int))); lastFocusDirection = FOCUS_NONE; focusType = FOCUS_MANUAL; HFRPlot->axis( KPlotWidget::LeftAxis )->setLabel( i18nc("Half Flux Radius", "HFR") ); HFRPlot->axis( KPlotWidget::BottomAxis )->setLabel( i18n("Absolute Position") ); resetButtons(); appendLogText(i18n("Idle.")); foreach(QString filter, FITSViewer::filterTypes) filterCombo->addItem(filter); exposureIN->setValue(Options::focusExposure()); toleranceIN->setValue(Options::focusTolerance()); stepIN->setValue(Options::focusTicks()); }
void Focus::autoFocusRel(double currentHFR) { QString deltaTxt = QString("%1").arg(fabs(currentHFR-HFR)*100.0, 0,'g', 2); QString HFRText = QString("%1").arg(currentHFR, 0,'g', 3); appendLogText(i18n("FITS received. HFR %1. Delta (%2%)", HFRText, deltaTxt)); if (pulseDuration <= 32) { appendLogText(i18n("Autofocus failed to reach proper focus. Try adjusting the tolerance value.")); stopFocus(); return; } if (currentHFR == -1) { appendLogText(i18n("No stars detected, capturing again...")); capture(); return; } switch (lastFocusDirection) { case FOCUS_NONE: HFR = currentHFR; FocusIn(pulseDuration); break; case FOCUS_IN: if (fabs(currentHFR - HFR) < (toleranceIN->value()/100.0) && HFRInc == 0) { appendLogText(i18n("Autofocus complete.")); stopFocus(); break; } else if (currentHFR < HFR) { HFR = currentHFR; FocusIn(pulseDuration); HFRInc=0; } else { HFRInc++; if (HFRInc < 1) { capture(); return; } else { HFR = currentHFR; HFRInc=0; if (reverseDir) pulseDuration /= 2; if (canAbsMove) { if (reverseDir) FocusOut(pulseDuration*3); else { reverseDir = true; FocusOut(pulseDuration*2); } } else FocusOut(pulseDuration); } } break; case FOCUS_OUT: if (fabs(currentHFR - HFR) < (toleranceIN->value()/100.0) && HFRInc == 0) { appendLogText(i18n("Autofocus complete.")); stopFocus(); break; } else if (currentHFR < HFR) { HFR = currentHFR; FocusOut(pulseDuration); HFRInc=0; } else { HFRInc++; if (HFRInc < 1) capture(); else { HFR = currentHFR; HFRInc=0; if (reverseDir) pulseDuration /= 2; if (canAbsMove) { if (reverseDir) FocusIn(pulseDuration*3); else { reverseDir = true; FocusIn(pulseDuration*2); } } else FocusIn(pulseDuration); } } break; } }
void Focus::autoFocusAbs(double currentHFR) { static int initHFRPos=0, lastHFRPos=0, minHFRPos=0, initSlopePos=0, initPulseDuration=0, focusOutLimit=0, focusInLimit=0, minPos=1e6, maxPos=0; static double initHFR=0, minHFR=0, maxHFR=1,initSlopeHFR=0; double targetPulse=0, delta=0; QString deltaTxt = QString("%1").arg(fabs(currentHFR-minHFR)*100.0, 0,'g', 2); QString HFRText = QString("%1").arg(currentHFR, 0,'g', 3); //qDebug() << "Current HFR: " << currentHFR << " Current Position: " << pulseStep << endl; //qDebug() << "minHFR: " << minHFR << " MinHFR Pos: " << minHFRPos << endl; //qDebug() << "Delta: " << deltaTxt << endl; if (minHFR) appendLogText(i18n("FITS received. HFR %1 @ %2. Delta (%3%)", HFRText, pulseStep, deltaTxt)); else appendLogText(i18n("FITS received. HFR %1 @ %2.", HFRText, pulseStep)); if (++absIterations > MAXIMUM_ABS_ITERATIONS) { appendLogText(i18n("Autofocus failed to reach proper focus. Try increasing tolerance value.")); stopFocus(); return; } // No stars detected, try to capture again if (currentHFR == -1) { appendLogText(i18n("No stars detected, capturing again...")); capture(); return; } if (currentHFR > maxHFR || HFRPoints.empty()) { maxHFR = currentHFR; if (HFRPoints.empty()) { maxPos=1; minPos=1e6; } } if (pulseStep > maxPos) maxPos = pulseStep; if (pulseStep < minPos) minPos = pulseStep; HFRPoint *p = new HFRPoint(); p->HFR = currentHFR; p->pos = pulseStep; HFRPoints.append(p); HFRPlot->removeAllPlotObjects(); //HFRPlot->setLimits(pulseStep-pulseDuration*5, pulseStep+pulseDuration*5, currentHFR/1.5, currentHFR*1.5 ); HFRPlot->setLimits(minPos-pulseDuration, maxPos+pulseDuration, currentHFR/1.5, maxHFR ); KPlotObject *hfrObj = new KPlotObject( Qt::red, KPlotObject::Points, 2 ); foreach(HFRPoint *p, HFRPoints) hfrObj->addPoint(p->pos, p->HFR); HFRPlot->addPlotObject(hfrObj); HFRPlot->update(); switch (lastFocusDirection) { case FOCUS_NONE: HFR = currentHFR; initHFRPos = pulseStep; initHFR=HFR; minHFR=currentHFR; minHFRPos=pulseStep; HFRDec=0; HFRInc=0; focusOutLimit=0; focusInLimit=0; initPulseDuration=pulseDuration; FocusIn(pulseDuration); break; case FOCUS_IN: case FOCUS_OUT: if (reverseDir && focusInLimit && focusOutLimit && fabs(currentHFR - minHFR) < (toleranceIN->value()/100.0) && HFRInc == 0 ) { if (absIterations <= 2) appendLogText(i18n("Change in HFR is too small. Try increasing the step size or decreasing the tolerance.")); else appendLogText(i18n("Autofocus complete.")); stopFocus(); break; } else if (currentHFR < HFR) { double slope=0; // Let's try to calculate slope of the V curve. if (initSlopeHFR == 0 && HFRInc == 0 && HFRDec >= 1) { initSlopeHFR = HFR; initSlopePos = lastHFRPos; } // Let's now limit the travel distance of the focuser if (lastFocusDirection == FOCUS_OUT && lastHFRPos < focusInLimit) focusInLimit = lastHFRPos; else if (lastFocusDirection == FOCUS_IN && lastHFRPos > focusOutLimit) focusOutLimit = lastHFRPos; // If we have slope, get next target position if (initSlopeHFR) { slope = (currentHFR - initSlopeHFR) / (pulseStep - initSlopePos); targetPulse = pulseStep + (currentHFR*0.5 - currentHFR)/slope; } // Otherwise proceed iteratively else { if (lastFocusDirection == FOCUS_IN) targetPulse = pulseStep + pulseDuration; else targetPulse = pulseStep - pulseDuration; } HFR = currentHFR; // Let's keep track of the minimum HFR if (HFR < minHFR) { minHFR = HFR; minHFRPos = pulseStep; } lastHFRPos = pulseStep; // HFR is decreasing, we are on the right direction HFRDec++; HFRInc=0; } else { // HFR increased, let's deal with it. HFRInc++; HFRDec=0; reverseDir = true; // Reality Check: If it's first time, let's capture again and see if it changes. if (HFRInc <= 1) { capture(); return; } // Looks like we're going away from optimal HFR else { HFR = currentHFR; lastHFRPos = pulseStep; initSlopeHFR=0; HFRInc=0; // Let's set new limits if (lastFocusDirection == FOCUS_IN) focusInLimit = pulseStep; else focusOutLimit = pulseStep; // Decrease pulse pulseDuration = pulseDuration * 0.75; // Let's get close to the minimum HFR position so far detected if (lastFocusDirection == FOCUS_OUT) targetPulse = minHFRPos+pulseDuration/2; else targetPulse = minHFRPos-pulseDuration/2; } } // Limit target Pulse to algorithm limits if (focusInLimit != 0 && lastFocusDirection == FOCUS_IN && targetPulse > focusInLimit) targetPulse = focusInLimit; else if (focusOutLimit != 0 && lastFocusDirection == FOCUS_OUT && targetPulse < focusOutLimit) targetPulse = focusOutLimit; // Limit target pulse to focuser limits if (targetPulse < absMotionMin) targetPulse = absMotionMin; else if (targetPulse > absMotionMax) targetPulse = absMotionMax; // Ops, we can't go any further, we're done. if (targetPulse == pulseStep) { appendLogText(i18n("Autofocus complete.")); stopFocus(); return; } // Ops, deadlock if (focusOutLimit && focusOutLimit == focusInLimit) { appendLogText(i18n("Deadlock reached. Please try again with different settings.")); stopFocus(); return; } // Get delta for next move delta = (targetPulse - pulseStep); // Now cross your fingers and wait if (delta > 0) FocusIn(delta); else FocusOut(fabs(delta)); break; } }