13#include "fitsviewer/fitsdata.h"
14#include "fitsviewer/fitsview.h"
15#include "auxiliary/kspaths.h"
16#include "ekos_guide_debug.h"
17#include "guidealgorithms.h"
19#include "../guideview.h"
20#include "linearguider.h"
21#include "hysteresisguider.h"
22#include "ekos/guide/opsguide.h"
33 GuiderUtils::Vector position;
34 if (usingSEPMultiStar())
36 QRect trackingBox = guideView->getTrackingBox();
37 position = guideStars.findGuideStar(imageData, trackingBox, guideView, firstFrame);
41 position = GuideAlgorithms::findLocalStarPosition(
42 imageData, m_StarDetectionAlgorithm, video_width, video_height,
43 guideView->getTrackingBox());
45 if (position.x == -1 || position.y == -1)
54 starPosition = GuiderUtils::Vector(0);
55 targetPosition = GuiderUtils::Vector(0);
60 driftUpto[GUIDE_RA] = driftUpto[GUIDE_DEC] = 0;
61 drift[GUIDE_RA] =
new double[CIRCULAR_BUFFER_SIZE];
62 drift[GUIDE_DEC] =
new double[CIRCULAR_BUFFER_SIZE];
63 memset(drift[GUIDE_RA], 0,
sizeof(
double) * CIRCULAR_BUFFER_SIZE);
64 memset(drift[GUIDE_DEC], 0,
sizeof(
double) * CIRCULAR_BUFFER_SIZE);
65 drift_integral[GUIDE_RA] = drift_integral[GUIDE_DEC] = 0;
69 m_RALinearGuider.reset(
new LinearGuider(
"RA"));
70 m_DECLinearGuider.reset(
new LinearGuider(
"DEC"));
71 m_RAHysteresisGuider.reset(
new HysteresisGuider(
"RA"));
72 m_DECHysteresisGuider.reset(
new HysteresisGuider(
"DEC"));
77 delete[] drift[GUIDE_RA];
78 delete[] drift[GUIDE_DEC];
81bool cgmath::setVideoParameters(
int vid_wd,
int vid_ht,
int binX,
int binY)
83 if (vid_wd <= 0 || vid_ht <= 0)
86 video_width = vid_wd / binX;
87 video_height = vid_ht / binY;
89 calibration.setBinningUsed(binX, binY);
90 guideStars.setCalibration(calibration);
95bool cgmath::setGuiderParameters(
double guider_aperture)
97 aperture = guider_aperture;
98 guideStars.setCalibration(calibration);
104void cgmath::createGuideLog()
108 QTextStream out(&logFile);
110 out <<
"Guiding rate,x15 arcsec/sec: " <<
Qt::endl;
111 out <<
"Focal,mm: " << calibration.getFocalLength() <<
Qt::endl;
112 out <<
"Aperture,mm: " << aperture <<
Qt::endl;
113 out <<
"F/D: " << calibration.getFocalLength() / aperture <<
Qt::endl;
114 out <<
"Frame #, Time Elapsed (ms), RA Error (arcsec), RA Correction (ms), RA Correction Direction, DEC Error "
115 "(arcsec), DEC Correction (ms), DEC Correction Direction"
121bool cgmath::setTargetPosition(
double x,
double y)
128 if (x >= (
double)video_width - 1)
129 x = (double)video_width - 1;
130 if (y >= (
double)video_height - 1)
131 y = (double)video_height - 1;
133 targetPosition = GuiderUtils::Vector(x, y, 0);
135 guideStars.setCalibration(calibration);
140bool cgmath::getTargetPosition(
double *x,
double *y)
const
142 *x = targetPosition.x;
143 *y = targetPosition.y;
147void cgmath::getStarScreenPosition(
double *dx,
double *dy)
const
149 *dx = starPosition.x;
150 *dy = starPosition.y;
155 iterationCounter = 0;
156 driftUpto[GUIDE_RA] = driftUpto[GUIDE_DEC] = 0;
157 drift_integral[GUIDE_RA] = drift_integral[GUIDE_DEC] = 0;
160 memset(drift[GUIDE_RA], 0,
sizeof(
double) * CIRCULAR_BUFFER_SIZE);
161 memset(drift[GUIDE_DEC], 0,
sizeof(
double) * CIRCULAR_BUFFER_SIZE);
166void cgmath::setStarDetectionAlgorithmIndex(
int algorithmIndex)
168 if (algorithmIndex < 0 || algorithmIndex > SEP_MULTISTAR)
171 m_StarDetectionAlgorithm = algorithmIndex;
174bool cgmath::usingSEPMultiStar()
const
176 return m_StarDetectionAlgorithm == SEP_MULTISTAR;
179void cgmath::updateCircularBuffers(
void)
183 driftUpto[GUIDE_RA]++;
184 driftUpto[GUIDE_DEC]++;
185 if (driftUpto[GUIDE_RA] >= CIRCULAR_BUFFER_SIZE)
186 driftUpto[GUIDE_RA] = 0;
187 if (driftUpto[GUIDE_DEC] >= CIRCULAR_BUFFER_SIZE)
188 driftUpto[GUIDE_DEC] = 0;
194 iterationCounter = 0;
195 driftUpto[GUIDE_RA] = driftUpto[GUIDE_DEC] = 0;
196 drift_integral[GUIDE_RA] = drift_integral[GUIDE_DEC] = 0;
199 memset(drift[GUIDE_RA], 0,
sizeof(
double) * CIRCULAR_BUFFER_SIZE);
200 memset(drift[GUIDE_DEC], 0,
sizeof(
double) * CIRCULAR_BUFFER_SIZE);
202 if (calibration.getFocalLength() > 0 && aperture > 0)
206 m_RALinearGuider->reset();
207 m_DECLinearGuider->reset();
208 m_RAHysteresisGuider->reset();
209 m_DECHysteresisGuider->reset();
215 m_RALinearGuider->reset();
216 m_DECLinearGuider->reset();
217 m_RAHysteresisGuider->reset();
218 m_DECHysteresisGuider->reset();
221void cgmath::suspend(
bool mode)
224 m_RALinearGuider->reset();
225 m_DECLinearGuider->reset();
226 m_RAHysteresisGuider->reset();
227 m_DECHysteresisGuider->reset();
230bool cgmath::isSuspended()
const
235bool cgmath::isStarLost()
const
240void cgmath::setLostStar(
bool is_lost)
249 if (raDEC == GUIDE_RA)
251 else if (raDEC == GUIDE_DEC)
257const QString directionStr(GuideDirection dir)
262 return "Decrease RA";
264 return "Increase RA";
266 return "Decrease DEC";
268 return "Increase DEC";
275bool cgmath::configureInParams(Ekos::GuideState state)
277 const bool dithering = state == Ekos::GuideState::GUIDE_DITHERING;
281 in_params.proportional_gain[0] = Options::rAProportionalGain();
282 in_params.proportional_gain[1] = Options::dECProportionalGain();
284 in_params.integral_gain[0] = Options::rAIntegralGain();
285 in_params.integral_gain[1] = Options::dECIntegralGain();
288 in_params.enabled[0] = Options::rAGuideEnabled();
289 in_params.enabled[1] = Options::dECGuideEnabled();
291 in_params.min_pulse_arcsec[0] = Options::rAMinimumPulseArcSec();
292 in_params.min_pulse_arcsec[1] = Options::dECMinimumPulseArcSec();
294 in_params.max_pulse_arcsec[0] = Options::rAMaximumPulseArcSec();
295 in_params.max_pulse_arcsec[1] = Options::dECMaximumPulseArcSec();
299 in_params.enabled_axis1[0] = Options::eastRAGuideEnabled();
301 in_params.enabled_axis2[0] = Options::westRAGuideEnabled();
305 in_params.enabled_axis1[1] = Options::northDECGuideEnabled();
307 in_params.enabled_axis2[1] = Options::southDECGuideEnabled();
312 in_params.proportional_gain[0] = 1.0;
313 in_params.proportional_gain[1] = 1.0;
314 in_params.integral_gain[0] = 0.0;
315 in_params.integral_gain[1] = 0.0;
316 in_params.min_pulse_arcsec[0] = 0.0;
317 in_params.min_pulse_arcsec[1] = 0.0;
318 in_params.max_pulse_arcsec[0] = Options::rAMaximumPulseArcSec();
319 in_params.max_pulse_arcsec[1] = Options::dECMaximumPulseArcSec();
320 in_params.enabled[0] =
true;
321 in_params.enabled[1] =
true;
322 in_params.enabled_axis1[0] =
true;
323 in_params.enabled_axis2[0] =
true;
324 in_params.enabled_axis1[1] =
true;
325 in_params.enabled_axis2[1] =
true;
331void cgmath::updateOutParams(
int k,
const double arcsecDrift,
int pulseLength, GuideDirection pulseDirection)
333 out_params.pulse_dir[k] = pulseDirection;
334 out_params.pulse_length[k] = pulseLength;
335 out_params.delta[k] = arcsecDrift;
338void cgmath::outputGuideLog()
340 if (Options::guideLogging())
342 QTextStream out(&logFile);
343 out << iterationCounter <<
"," << logTime.elapsed() <<
"," << out_params.delta[0] <<
"," << out_params.pulse_length[0] <<
345 << directionStr(out_params.pulse_dir[0]) <<
"," << out_params.delta[1] <<
","
346 << out_params.pulse_length[1] <<
"," << directionStr(out_params.pulse_dir[1]) <<
Qt::endl;
350void cgmath::processAxis(
const int k,
const bool dithering,
const bool darkGuide,
const Seconds &timeStep,
354 GuideDirection pulseDirection = NO_DIR;
359 const int idx = driftUpto[k];
360 const double arcsecDrift = drift[k][idx];
362 const double pulseConverter = (k == GUIDE_RA) ?
363 calibration.raPulseMillisecondsPerArcsecond() :
364 calibration.decPulseMillisecondsPerArcsecond();
365 const double maxPulseMilliseconds = in_params.max_pulse_arcsec[k] * pulseConverter;
369 m_RALinearGuider->reset();
370 m_DECLinearGuider->reset();
371 m_RAHysteresisGuider->reset();
372 m_DECHysteresisGuider->reset();
374 LinearGuider *lGuider =
nullptr;
375 HysteresisGuider *hGuider =
nullptr;
379 if ((Options::rAGuidePulseAlgorithm() == Ekos::OpsGuide::HYSTERESIS_ALGORITHM) && k == GUIDE_RA)
380 hGuider = m_RAHysteresisGuider.get();
381 else if ((Options::dECGuidePulseAlgorithm() == Ekos::OpsGuide::HYSTERESIS_ALGORITHM) && k == GUIDE_DEC)
382 hGuider = m_DECHysteresisGuider.get();
383 else if ((Options::rAGuidePulseAlgorithm() == Ekos::OpsGuide::LINEAR_ALGORITHM) && k == GUIDE_RA)
384 lGuider = m_RALinearGuider.get();
385 else if ((Options::dECGuidePulseAlgorithm() == Ekos::OpsGuide::LINEAR_ALGORITHM) && k == GUIDE_DEC)
386 lGuider = m_DECLinearGuider.get();
387 else if ((Options::rAGuidePulseAlgorithm() == Ekos::OpsGuide::GPG_ALGORITHM) && (k == GUIDE_RA)
388 && in_params.enabled[k])
392 if (useGPG && darkGuide)
394 gpg->darkGuiding(&pulseLength, &dir, calibration, timeStep);
395 pulseDirection =
dir;
400 qCDebug(KSTARS_EKOS_GUIDE) <<
"Warning: dark guiding without GPG or while dithering.";
403 else if (useGPG && gpg->computePulse(arcsecDrift,
404 usingSEPMultiStar() ? &guideStars :
nullptr, &pulseLength, &dir, calibration, timeStep))
406 pulseDirection =
dir;
407 pulseLength = std::min(pulseLength,
static_cast<int>(maxPulseMilliseconds + 0.5));
409 else if (lGuider !=
nullptr)
421 lGuider->setGain(Options::rAProportionalGain());
422 lGuider->setMinMove(Options::rAMinimumPulseArcSec());
423 pulse = lGuider->guide(arcsecDrift) * calibration.raPulseMillisecondsPerArcsecond();
424 pulseDirection = pulse > 0 ? RA_DEC_DIR : RA_INC_DIR;
428 lGuider->setGain(Options::dECProportionalGain());
429 lGuider->setMinMove(Options::dECMinimumPulseArcSec());
430 pulse = lGuider->guide(arcsecDrift) * calibration.decPulseMillisecondsPerArcsecond();
431 pulseDirection = pulse > 0 ? DEC_DEC_DIR : DEC_INC_DIR;
433 pulseLength = std::min(fabs(pulse), maxPulseMilliseconds);
435 else if (hGuider !=
nullptr)
440 hGuider->setGain(Options::rAProportionalGain());
441 hGuider->setMinMove(Options::rAMinimumPulseArcSec());
442 hGuider->setHysteresis(Options::rAHysteresis());
443 pulse = hGuider->guide(arcsecDrift) * calibration.raPulseMillisecondsPerArcsecond();
444 pulseDirection = pulse > 0 ? RA_DEC_DIR : RA_INC_DIR;
448 hGuider->setGain(Options::dECProportionalGain());
449 hGuider->setMinMove(Options::dECMinimumPulseArcSec());
450 hGuider->setHysteresis(Options::dECHysteresis());
451 pulse = hGuider->guide(arcsecDrift) * calibration.decPulseMillisecondsPerArcsecond();
452 pulseDirection = pulse > 0 ? DEC_DEC_DIR : DEC_INC_DIR;
454 pulseLength = std::min(fabs(pulse), maxPulseMilliseconds);
463 drift_integral[k] = 0;
464 for (
int i = 0; i < CIRCULAR_BUFFER_SIZE; ++i)
465 drift_integral[k] += drift[k][i];
466 drift_integral[k] /= (double)CIRCULAR_BUFFER_SIZE;
468 if (in_params.integral_gain[k] > 0)
469 qCDebug(KSTARS_EKOS_GUIDE) <<
label <<
"drift[" << axisStr(k) <<
"] = " << arcsecDrift
470 <<
" integral[" << axisStr(k) <<
"] = " << drift_integral[k];
472 const double arcsecPerMsPulse = k == GUIDE_RA ? calibration.raPulseMillisecondsPerArcsecond() :
473 calibration.decPulseMillisecondsPerArcsecond();
474 const double proportionalResponse = arcsecDrift * in_params.proportional_gain[k] * arcsecPerMsPulse;
475 const double integralResponse = drift_integral[k] * in_params.integral_gain[k] * arcsecPerMsPulse;
476 pulseLength = std::min(fabs(proportionalResponse + integralResponse), maxPulseMilliseconds);
480 if (!in_params.enabled[k] ||
482 (arcsecDrift > 0 && !in_params.enabled_axis1[k]) ||
484 (arcsecDrift < 0 && !in_params.enabled_axis2[k]))
486 pulseDirection = NO_DIR;
492 const double pulseArcSec = pulseConverter > 0 ? pulseLength / pulseConverter : 0;
493 if (pulseArcSec >= in_params.min_pulse_arcsec[k])
498 pulseDirection = arcsecDrift > 0 ? RA_DEC_DIR : RA_INC_DIR;
500 pulseDirection = arcsecDrift > 0 ? DEC_DEC_DIR : DEC_INC_DIR;
503 pulseDirection = NO_DIR;
508 constexpr int MAX_PULSE_MILLISECONDS = 5000;
509 if (pulseLength > MAX_PULSE_MILLISECONDS)
511 qCDebug(KSTARS_EKOS_GUIDE) <<
i18n(
"Limited long pulse of %1ms to %2ms", pulseLength, MAX_PULSE_MILLISECONDS);
512 pulseLength = MAX_PULSE_MILLISECONDS;
514 updateOutParams(k, arcsecDrift, pulseLength, pulseDirection);
517void cgmath::calculatePulses(Ekos::GuideState state,
const std::pair<Seconds, Seconds> &timeStep)
519 const bool dithering = configureInParams(state);
521 processAxis(GUIDE_RA, dithering,
false, timeStep.first,
"Guiding:");
522 processAxis(GUIDE_DEC, dithering,
false, timeStep.second,
"Guiding:");
524 qCDebug(KSTARS_EKOS_GUIDE)
525 << QString(
"Guiding pulses: RA: %1ms %2 DEC: %3ms %4")
526 .arg(out_params.pulse_length[GUIDE_RA]).arg(directionStr(out_params.pulse_dir[GUIDE_RA]))
527 .arg(out_params.pulse_length[GUIDE_DEC]).arg(directionStr(out_params.pulse_dir[GUIDE_DEC]));
534 const std::pair<Seconds, Seconds> &timeStep, GuideLog * logger)
538 m_RALinearGuider->reset();
539 m_DECLinearGuider->reset();
540 m_RAHysteresisGuider->reset();
541 m_DECHysteresisGuider->reset();
542 if (Options::rAGuidePulseAlgorithm() == Ekos::OpsGuide::GPG_ALGORITHM)
544 GuiderUtils::Vector guideStarPosition = findLocalStarPosition(imageData, guideView,
false);
545 if (guideStarPosition.x != -1 && !std::isnan(guideStarPosition.x))
547 gpg->suspended(guideStarPosition, targetPosition,
548 usingSEPMultiStar() ? &guideStars :
nullptr, calibration);
557 GuiderUtils::Vector starPositionArcSec, targetPositionArcSec;
560 starPosition = findLocalStarPosition(imageData, guideView,
false);
563 if (starPosition.x == -1 || std::isnan(starPosition.x))
566 if (logger !=
nullptr && state == Ekos::GUIDE_GUIDING)
568 GuideLog::GuideData data;
569 data.code = GuideLog::GuideData::NO_STAR_FOUND;
570 data.type = GuideLog::GuideData::DROP;
571 logger->addGuideData(data);
579 QVector3D starCenter(starPosition.x, starPosition.y, 0);
580 emit newStarPosition(starCenter,
true);
583 if (state == Ekos::GUIDE_CALIBRATING)
586 if (state == Ekos::GUIDE_GUIDING && (targetPosition.x <= 0.0 || targetPosition.y <= 0.0))
588 qCDebug(KSTARS_EKOS_GUIDE) <<
"Guiding with target 0.0 -- something's wrong!!!!!!!!!!!";
589 for (
int k = GUIDE_RA; k <= GUIDE_DEC; k++)
591 out_params.pulse_dir[k] = NO_DIR;
592 out_params.pulse_length[k] = 0;
593 out_params.delta[k] = 0;
601 starPositionArcSec = calibration.convertToArcseconds(starPosition);
602 targetPositionArcSec = calibration.convertToArcseconds(targetPosition);
605 const GuiderUtils::Vector star_xy_arcsec_drift = starPositionArcSec - targetPositionArcSec;
606 const GuiderUtils::Vector star_drift = calibration.rotateToRaDec(star_xy_arcsec_drift);
612 drift[GUIDE_RA][driftUpto[GUIDE_RA]] = star_drift.x;
613 drift[GUIDE_DEC][driftUpto[GUIDE_DEC]] = star_drift.y;
615 qCDebug(KSTARS_EKOS_GUIDE)
616 << QString(
"Star %1 %2 a-s %3 %4 Target %5 %6 a-s %7 %8 Drift: RA %9 DEC %10")
617 .arg(starPosition.x, 0,
'f', 1) .arg(starPosition.y, 0,
'f', 1)
618 .arg(starPositionArcSec.x, 0,
'f', 1) .arg(starPositionArcSec.y, 0,
'f', 1)
619 .arg(targetPosition.x, 0,
'f', 1) .arg(targetPosition.y, 0,
'f', 1)
620 .arg(targetPositionArcSec.x, 0,
'f', 1).arg(targetPositionArcSec.y, 0,
'f', 1)
621 .arg(star_drift.x, 0,
'f', 2) .arg(star_drift.y, 0,
'f', 2);
623 if (state == Ekos::GUIDE_GUIDING && usingSEPMultiStar())
625 double multiStarRADrift, multiStarDECDrift;
626 if (guideStars.getDrift(sqrt(star_drift.x * star_drift.x + star_drift.y * star_drift.y),
627 targetPosition.x, targetPosition.y,
628 &multiStarRADrift, &multiStarDECDrift))
630 qCDebug(KSTARS_EKOS_GUIDE) << QString(
"MultiStar drift: RA %1 DEC %2")
631 .arg(multiStarRADrift, 0,
'f', 2)
632 .arg(multiStarDECDrift, 0,
'f', 2);
633 drift[GUIDE_RA][driftUpto[GUIDE_RA]] = multiStarRADrift;
634 drift[GUIDE_DEC][driftUpto[GUIDE_DEC]] = multiStarDECDrift;
638 qCDebug(KSTARS_EKOS_GUIDE) <<
"MultiStar: failed, fell back to guide star";
644 const double raDrift = drift[GUIDE_RA][driftUpto[GUIDE_RA]];
645 const double decDrift = drift[GUIDE_DEC][driftUpto[GUIDE_DEC]];
648 calculatePulses(state, timeStep);
650 if (state == Ekos::GUIDE_GUIDING)
654 updateCircularBuffers();
656 qCDebug(KSTARS_EKOS_GUIDE) << QString(
"performProcessing took %1s").arg(timer.
elapsed() / 1000.0, 0,
'f', 3);
658 if (logger !=
nullptr)
660 GuideLog::GuideData data;
661 data.type = GuideLog::GuideData::MOUNT;
664 data.dx = starPosition.x - targetPosition.x;
665 data.dy = starPosition.y - targetPosition.y;
667 calibration.convertToPixels(-raDrift, -decDrift, &data.raDistance, &data.decDistance);
669 const double raGuideFactor = out_params.pulse_dir[GUIDE_RA] == NO_DIR ?
670 0 : (out_params.pulse_dir[GUIDE_RA] == RA_INC_DIR ? -1.0 : 1.0);
671 const double decGuideFactor = out_params.pulse_dir[GUIDE_DEC] == NO_DIR ?
672 0 : (out_params.pulse_dir[GUIDE_DEC] == DEC_INC_DIR ? 1.0 : -1.0);
676 data.raGuideDistance = calibration.xPixelsPerArcsecond() * raGuideFactor * out_params.pulse_length[GUIDE_RA] /
677 calibration.raPulseMillisecondsPerArcsecond();
678 data.decGuideDistance = calibration.yPixelsPerArcsecond() * decGuideFactor * out_params.pulse_length[GUIDE_DEC] /
679 calibration.decPulseMillisecondsPerArcsecond();
681 data.raDuration = out_params.pulse_dir[GUIDE_RA] == NO_DIR ? 0 : out_params.pulse_length[GUIDE_RA];
682 data.raDirection = out_params.pulse_dir[GUIDE_RA];
683 data.decDuration = out_params.pulse_dir[GUIDE_DEC] == NO_DIR ? 0 : out_params.pulse_length[GUIDE_DEC];
684 data.decDirection = out_params.pulse_dir[GUIDE_DEC];
685 data.code = GuideLog::GuideData::NO_ERRORS;
686 data.snr = guideStars.getGuideStarSNR();
687 data.mass = guideStars.getGuideStarMass();
689 logger->addGuideData(data);
693void cgmath::performDarkGuiding(Ekos::GuideState state,
const std::pair<Seconds, Seconds> &timeStep)
696 const bool dithering = configureInParams(state);
699 processAxis(GUIDE_RA, dithering,
true, timeStep.first,
"Dark Guiding:");
700 qCDebug(KSTARS_EKOS_GUIDE)
701 << QString(
"Dark Guiding pulses: RA: %1ms %2")
702 .arg(out_params.pulse_length[GUIDE_RA]).arg(directionStr(out_params.pulse_dir[GUIDE_RA]));
706 updateOutParams(GUIDE_DEC, 0, 0, NO_DIR);
711void cgmath::emitStats()
714 if (out_params.pulse_dir[GUIDE_RA] == RA_DEC_DIR)
715 pulseRA = out_params.pulse_length[GUIDE_RA];
716 else if (out_params.pulse_dir[GUIDE_RA] == RA_INC_DIR)
717 pulseRA = -out_params.pulse_length[GUIDE_RA];
719 if (out_params.pulse_dir[GUIDE_DEC] == DEC_DEC_DIR)
720 pulseDEC = -out_params.pulse_length[GUIDE_DEC];
721 else if (out_params.pulse_dir[GUIDE_DEC] == DEC_INC_DIR)
722 pulseDEC = out_params.pulse_length[GUIDE_DEC];
724 const bool hasGuidestars = usingSEPMultiStar();
725 const double snr = hasGuidestars ? guideStars.getGuideStarSNR() : 0;
726 const double skyBG = hasGuidestars ? guideStars.skybackground().mean : 0;
727 const int numStars = hasGuidestars ? guideStars.skybackground().starsDetected : 0;
730 emit guideStats(-out_params.delta[GUIDE_RA], out_params.delta[GUIDE_DEC],
731 pulseRA, pulseDEC, snr, skyBG, numStars);
734void cgmath::calculateRmsError(
void)
739 if (iterationCounter == 0)
742 int count = std::min(iterationCounter,
static_cast<unsigned int>(CIRCULAR_BUFFER_SIZE));
743 for (
int k = GUIDE_RA; k <= GUIDE_DEC; k++)
749 for (
int i = 0; i < count; ++i)
752 sumYSq += drift[k][i] * drift[k][i];
756 double variance = count < 2 ? 0 : (count * sumYSq - sumY * sumY) / (count * count);
758 out_params.sigma[k] = sqrt(variance);
760 out_params.sigma[k] = 0.0;
767 return guideStars.selectGuideStar(imageData);
770double cgmath::getGuideStarSNR()
772 return guideStars.getGuideStarSNR();
776cproc_in_params::cproc_in_params()
781void cproc_in_params::reset(
void)
785 for (
int k = GUIDE_RA; k <= GUIDE_DEC; k++)
788 integral_gain[k] = 0;
789 max_pulse_arcsec[k] = 5000;
790 min_pulse_arcsec[k] = 0;
794cproc_out_params::cproc_out_params()
799void cproc_out_params::reset(
void)
801 for (
int k = GUIDE_RA; k <= GUIDE_DEC; k++)
804 pulse_dir[k] = NO_DIR;
QString i18n(const char *text, const TYPE &arg...)
KIOCORE_EXPORT QString dir(const QString &fileClass)
QString label(StandardShortcut id)
QCA_EXPORT Logger * logger()
qint64 elapsed() const const
QTextStream & endl(QTextStream &stream)