1#include "calibrationprocess.h"
4#include "ekos_guide_debug.h"
13QString stageString(Ekos::CalibrationProcess::CalibrationStage stage)
17 case Ekos::CalibrationProcess::CAL_IDLE:
19 case Ekos::CalibrationProcess::CAL_ERROR:
21 case Ekos::CalibrationProcess::CAL_CAPTURE_IMAGE:
22 return(
"CAL_CAPTURE_IMAGE");
23 case Ekos::CalibrationProcess::CAL_SELECT_STAR:
24 return(
"CAL_SELECT_STAR");
25 case Ekos::CalibrationProcess::CAL_START:
27 case Ekos::CalibrationProcess::CAL_RA_INC:
29 case Ekos::CalibrationProcess::CAL_RA_DEC:
31 case Ekos::CalibrationProcess::CAL_DEC_INC:
32 return(
"CAL_DEC_INC");
33 case Ekos::CalibrationProcess::CAL_DEC_DEC:
34 return(
"CAL_DEC_DEC");
35 case Ekos::CalibrationProcess::CAL_BACKLASH:
36 return(
"CAL_BACKLASH");
42CalibrationProcess::CalibrationProcess(
double startX,
double startY,
bool raOnlyEnabled)
44 calibrationStage = CAL_START;
45 raOnly = raOnlyEnabled;
50void CalibrationProcess::useCalibration(Calibration *calibrationPtr)
52 calibration = calibrationPtr;
53 tempCalibration = *calibration;
56void CalibrationProcess::startup()
58 calibrationStage = CAL_START;
61void CalibrationProcess::setGuideLog(GuideLog *guideLogPtr)
63 guideLog = guideLogPtr;
66bool CalibrationProcess::inProgress()
const
68 return calibrationStage > CAL_START;
71void CalibrationProcess::addCalibrationUpdate(
72 GuideInterface::CalibrationUpdateType type,
73 QString message,
double x,
double y)
76 calibrationUpdate = message;
81void CalibrationProcess::getCalibrationUpdate(
82 GuideInterface::CalibrationUpdateType *type,
83 QString *message,
double *x,
double *y)
const
86 *message = calibrationUpdate;
91QString CalibrationProcess::getLogStatus()
const
96void CalibrationProcess::addLogStatus(
const QString &message)
101void CalibrationProcess::addPulse(GuideDirection dir,
int msecs)
103 pulseDirection =
dir;
107void CalibrationProcess::getPulse(GuideDirection *dir,
int *msecs)
const
109 *
dir = pulseDirection;
113void CalibrationProcess::addStatus(Ekos::GuideState s)
118Ekos::GuideState CalibrationProcess::getStatus()
const
123void CalibrationProcess::initializeIteration()
125 axisCalibrationComplete =
false;
129 calibrationUpdate.
clear();
130 updateType = GuideInterface::CALIBRATION_MESSAGE_ONLY;
134 addStatus(Ekos::GUIDE_CALIBRATING);
136 pulseDirection = NO_DIR;
140void CalibrationProcess::iterate(
double x,
double y)
142 initializeIteration();
143 switch (calibrationStage)
155 decBacklashState(x, y);
168void CalibrationProcess::startState()
170 maximumSteps = Options::autoModeIterations();
171 turn_back_time = maximumSteps * 7;
175 backlash_iterations = 0;
176 ra_total_pulse = de_total_pulse = 0;
178 addLogStatus(
i18n(
"RA drifting forward..."));
180 last_pulse = Options::calibrationPulseDuration();
182 addCalibrationUpdate(GuideInterface::RA_OUT,
i18n(
"Guide Star found."), 0, 0);
184 qCDebug(KSTARS_EKOS_GUIDE) <<
"Auto Iteration #" << maximumSteps <<
"Default pulse:" << last_pulse;
185 qCDebug(KSTARS_EKOS_GUIDE) <<
"Start X1 " << start_x1 <<
" Start Y1 " << start_y1;
190 addPulse(RA_INC_DIR, last_pulse);
194 calibrationStage = CAL_RA_INC;
196 guideLog->addCalibrationData(RA_INC_DIR, start_x1, start_y1, start_x1, start_y1);
200void CalibrationProcess::raOutState(
double cur_x,
double cur_y)
202 addCalibrationUpdate(GuideInterface::RA_OUT,
i18n(
"Calibrating RA Out"),
203 cur_x - start_x1, cur_y - start_y1);
205 qCDebug(KSTARS_EKOS_GUIDE) <<
"Iteration #" << ra_iterations <<
": STAR " << cur_x <<
"," << cur_y;
206 qCDebug(KSTARS_EKOS_GUIDE) <<
"Iteration " << ra_iterations <<
" Direction: RA_INC_DIR" <<
" Duration: "
207 << last_pulse <<
" ms.";
210 guideLog->addCalibrationData(RA_INC_DIR, cur_x, cur_y, start_x1, start_y1);
214 const double xDrift = cur_x - start_x1;
215 const double yDrift = cur_y - start_y1;
216 if (((ra_iterations >= maximumSteps) ||
217 (std::hypot(xDrift, yDrift) > Options::calibrationMaxMove()))
218 && (fabs(xDrift) > 1.5 || fabs(yDrift) > 1.5))
220 ra_total_pulse += last_pulse;
221 calibrationStage = CAL_RA_DEC;
229 qCDebug(KSTARS_EKOS_GUIDE) <<
"End X1 " << end_x1 <<
" End Y1 " << end_y1;
233 tempCalibration.calculate1D(start_x1, start_y1, end_x1, end_y1, ra_total_pulse);
238 addPulse(RA_DEC_DIR, last_pulse);
241 addLogStatus(
i18n(
"RA drifting reverse..."));
243 guideLog->endCalibrationSection(RA_INC_DIR, tempCalibration.getAngle());
245 else if (ra_iterations > turn_back_time)
247 addLogStatus(
i18n(
"Calibration rejected. Star drift is too short. Check for mount, cable, or backlash problems."));
248 calibrationStage = CAL_ERROR;
249 addStatus(Ekos::GUIDE_CALIBRATION_ERROR);
250 addCalibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY,
i18n(
"Calibration Failed: Drift too short."));
252 guideLog->endCalibration(0, 0);
257 if (fabs(cur_x - last_x) < 0.5 && fabs(cur_y - last_y) < 0.5)
260 last_pulse = Options::calibrationPulseDuration() * 2;
264 ra_total_pulse += last_pulse;
265 last_pulse = Options::calibrationPulseDuration();
271 addPulse(RA_INC_DIR, last_pulse);
277void CalibrationProcess::raInState(
double cur_x,
double cur_y)
279 addCalibrationUpdate(GuideInterface::RA_IN,
i18n(
"Calibrating RA In"),
280 cur_x - start_x1, cur_y - start_y1);
281 qCDebug(KSTARS_EKOS_GUIDE) <<
"Iteration #" << ra_iterations <<
": STAR " << cur_x <<
"," << cur_y;
282 qCDebug(KSTARS_EKOS_GUIDE) <<
"Iteration " << ra_iterations <<
" Direction: RA_DEC_DIR" <<
" Duration: "
283 << last_pulse <<
" ms.";
285 double driftRA, driftDEC;
286 tempCalibration.computeDrift(GuiderUtils::Vector(cur_x, cur_y, 0), GuiderUtils::Vector(start_x1, start_y1, 0),
287 &driftRA, &driftDEC);
289 qCDebug(KSTARS_EKOS_GUIDE) <<
"Star x pos is " << driftRA <<
" from original point.";
291 if (ra_distance == 0.0)
292 ra_distance = driftRA;
295 guideLog->addCalibrationData(RA_DEC_DIR, cur_x, cur_y, start_x1, start_y1);
300 last_pulse = Options::calibrationPulseDuration();
301 axisCalibrationComplete =
true;
305 else if ( (fabs(cur_x - last_x) < 0.5 && fabs(cur_y - last_y) < 0.5)
306 || driftRA > ra_distance)
312 last_pulse = Options::calibrationPulseDuration() * 2;
314 last_pulse = Options::calibrationPulseDuration();
319 last_pulse = Options::calibrationPulseDuration();
325 if (axisCalibrationComplete ==
false)
327 if (ra_iterations < turn_back_time)
329 addPulse(RA_DEC_DIR, last_pulse);
334 calibrationStage = CAL_ERROR;
335 addStatus(Ekos::GUIDE_CALIBRATION_ERROR);
336 addCalibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY,
i18n(
"Calibration Failed: couldn't reach start."));
337 addLogStatus(
i18np(
"Guide RA: Scope cannot reach the start point after %1 iteration. Possible mount or "
338 "backlash problems...",
339 "GUIDE_RA: Scope cannot reach the start point after %1 iterations. Possible mount or "
340 "backlash problems...",
347 if (Options::guideCalibrationBacklash())
349 calibrationStage = CAL_BACKLASH;
352 start_backlash_x = cur_x;
353 start_backlash_y = cur_y;
354 addPulse(DEC_INC_DIR, Options::calibrationPulseDuration());
355 backlash_iterations++;
356 addLogStatus(
i18n(
"DEC backlash..."));
360 calibrationStage = CAL_DEC_INC;
366 qCDebug(KSTARS_EKOS_GUIDE) <<
"Start X2 " << start_x2 <<
" start Y2 " << start_y2;
367 addPulse(DEC_INC_DIR, Options::calibrationPulseDuration());
369 addLogStatus(
i18n(
"DEC drifting forward..."));
374 if (calibration->calculate1D(start_x1, start_y1, end_x1, end_y1, ra_total_pulse))
377 calibrationStage = CAL_IDLE;
378 addStatus(Ekos::GUIDE_CALIBRATION_SUCCESS);
381 guideLog->endCalibration(1000.0 / calibration->raPulseMillisecondsPerArcsecond(), 0);
385 addLogStatus(
i18n(
"Calibration rejected. Star drift is too short. Check for mount, cable, or backlash problems."));
386 calibrationStage = CAL_ERROR;
387 addStatus(Ekos::GUIDE_CALIBRATION_ERROR);
388 addCalibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY,
i18n(
"Calibration Failed: drift too short."));
390 guideLog->endCalibration(0, 0);
394void CalibrationProcess::decBacklashState(
double cur_x,
double cur_y)
396 double driftRA, driftDEC;
397 tempCalibration.computeDrift(
398 GuiderUtils::Vector(cur_x, cur_y, 0),
399 GuiderUtils::Vector(start_backlash_x, start_backlash_y, 0),
400 &driftRA, &driftDEC);
404 constexpr int MIN_DEC_BACKLASH_MOVE_PIXELS = 3;
405 if ((++backlash_iterations >= 5) ||
406 (fabs(driftDEC) > MIN_DEC_BACKLASH_MOVE_PIXELS))
408 addCalibrationUpdate(GuideInterface::BACKLASH,
i18n(
"Calibrating DEC Backlash"),
409 cur_x - start_x1, cur_y - start_y1);
410 qCDebug(KSTARS_EKOS_GUIDE) <<
QString(
"Stopping dec backlash caibration after %1 iterations, offset %2")
411 .
arg(backlash_iterations - 1)
412 .
arg(driftDEC, 4,
'f', 2);
413 calibrationStage = CAL_DEC_INC;
419 qCDebug(KSTARS_EKOS_GUIDE) <<
"Start X2 " << start_x2 <<
" start Y2 " << start_y2;
420 addPulse(DEC_INC_DIR, Options::calibrationPulseDuration());
422 addLogStatus(
i18n(
"DEC drifting forward..."));
425 addCalibrationUpdate(GuideInterface::BACKLASH,
i18n(
"Calibrating DEC Backlash"),
426 cur_x - start_x1, cur_y - start_y1);
427 qCDebug(KSTARS_EKOS_GUIDE) <<
"Backlash iter" << backlash_iterations <<
"position" << cur_x << cur_y;
428 addPulse(DEC_INC_DIR, Options::calibrationPulseDuration());
432void CalibrationProcess::decOutState(
double cur_x,
double cur_y)
434 addCalibrationUpdate(GuideInterface::DEC_OUT,
i18n(
"Calibrating DEC Out"),
435 cur_x - start_x1, cur_y - start_y1);
437 qCDebug(KSTARS_EKOS_GUIDE) <<
"Iteration #" << dec_iterations <<
": STAR " << cur_x <<
"," << cur_y;
438 qCDebug(KSTARS_EKOS_GUIDE) <<
"Iteration " << dec_iterations <<
" Direction: DEC_INC_DIR" <<
439 " Duration: " << last_pulse <<
" ms.";
443 guideLog->addCalibrationData(DEC_INC_DIR, cur_x, cur_y,
445 const double xDrift = cur_x - start_x2;
446 const double yDrift = cur_y - start_y2;
447 if (((dec_iterations >= maximumSteps) ||
448 (std::hypot(xDrift, yDrift) > Options::calibrationMaxMove()))
449 && (fabs(xDrift) > 1.5 || fabs(yDrift) > 1.5))
451 calibrationStage = CAL_DEC_DEC;
453 de_total_pulse += last_pulse;
461 axisCalibrationComplete =
false;
463 qCDebug(KSTARS_EKOS_GUIDE) <<
"End X2 " << end_x2 <<
" End Y2 " << end_y2;
465 tempCalibration.calculate1D(start_x2, start_y2, end_x2, end_y2, de_total_pulse);
469 addPulse(DEC_DEC_DIR, last_pulse);
470 addLogStatus(
i18n(
"DEC drifting reverse..."));
473 guideLog->endCalibrationSection(DEC_INC_DIR, tempCalibration.getAngle());
475 else if (dec_iterations > turn_back_time)
477 calibrationStage = CAL_ERROR;
479 addStatus(Ekos::GUIDE_CALIBRATION_ERROR);
480 addCalibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY,
i18n(
"Calibration Failed: couldn't reach start point."));
481 addLogStatus(
i18np(
"Guide DEC: Scope cannot reach the start point after %1 iteration.\nPossible mount "
482 "or backlash problems...",
483 "GUIDE DEC: Scope cannot reach the start point after %1 iterations.\nPossible mount "
484 "or backlash problems...",
488 guideLog->endCalibration(0, 0);
492 if (fabs(cur_x - last_x) < 0.5 && fabs(cur_y - last_y) < 0.5)
495 last_pulse = Options::calibrationPulseDuration() * 2;
499 de_total_pulse += last_pulse;
500 last_pulse = Options::calibrationPulseDuration();
505 addPulse(DEC_INC_DIR, last_pulse);
511void CalibrationProcess::decInState(
double cur_x,
double cur_y)
513 addCalibrationUpdate(GuideInterface::DEC_IN,
i18n(
"Calibrating DEC In"),
514 cur_x - start_x1, cur_y - start_y1);
517 qCDebug(KSTARS_EKOS_GUIDE) <<
"Iteration #" << dec_iterations <<
": STAR " << cur_x <<
"," << cur_y;
518 qCDebug(KSTARS_EKOS_GUIDE) <<
"Iteration " << dec_iterations <<
" Direction: DEC_DEC_DIR" <<
519 " Duration: " << last_pulse <<
" ms.";
523 double driftRA, driftDEC;
524 tempCalibration.computeDrift(
525 GuiderUtils::Vector(cur_x, cur_y, 0),
526 GuiderUtils::Vector(start_x1, start_y1, 0),
527 &driftRA, &driftDEC);
529 qCDebug(KSTARS_EKOS_GUIDE) <<
"Currently " << driftRA << driftDEC <<
" from original point.";
532 if (de_distance == 0.0)
533 de_distance = driftRA;
536 guideLog->addCalibrationData(DEC_DEC_DIR, cur_x, cur_y, start_x2, start_y2);
541 last_pulse = Options::calibrationPulseDuration();
542 axisCalibrationComplete =
true;
545 else if ( (fabs(cur_x - last_x) < 0.5 && fabs(cur_y - last_y) < 0.5)
546 || driftRA > de_distance)
549 last_pulse = Options::calibrationPulseDuration() * 2;
553 last_pulse = Options::calibrationPulseDuration();
556 if (axisCalibrationComplete ==
false)
558 if (dec_iterations < turn_back_time)
560 addPulse(DEC_DEC_DIR, last_pulse);
565 calibrationStage = CAL_ERROR;
567 addStatus(Ekos::GUIDE_CALIBRATION_ERROR);
568 addCalibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY,
i18n(
"Calibration Failed: couldn't reach start point."));
570 addLogStatus(
i18np(
"Guide DEC: Scope cannot reach the start point after %1 iteration.\nPossible mount "
571 "or backlash problems...",
572 "Guide DEC: Scope cannot reach the start point after %1 iterations.\nPossible mount "
573 "or backlash problems...",
578 bool swap_dec =
false;
580 if (calibration->calculate2D(start_x1, start_y1, end_x1, end_y1, start_x2, start_y2, end_x2, end_y2,
581 &swap_dec, ra_total_pulse, de_total_pulse))
584 calibrationStage = CAL_IDLE;
586 addLogStatus(
i18n(
"DEC swap enabled."));
588 addLogStatus(
i18n(
"DEC swap disabled."));
590 addStatus(Ekos::GUIDE_CALIBRATION_SUCCESS);
592 addCalibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY,
i18n(
"Calibration Successful"));
596 guideLog->endCalibration(
597 1000.0 / calibration->raPulseMillisecondsPerArcsecond(),
598 1000.0 / calibration->decPulseMillisecondsPerArcsecond());
603 addLogStatus(
i18n(
"Calibration rejected. Star drift is too short. Check for mount, cable, or backlash problems."));
604 addCalibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY,
i18n(
"Calibration Failed: drift too short."));
605 addStatus(Ekos::GUIDE_CALIBRATION_ERROR);
606 calibrationStage = CAL_ERROR;
608 guideLog->endCalibration(0, 0);
QString i18np(const char *singular, const char *plural, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
Ekos is an advanced Astrophotography tool for Linux.
VehicleSection::Type type(QStringView coachNumber, QStringView coachClassification)
KIOCORE_EXPORT QString dir(const QString &fileClass)
QString arg(Args &&... args) const const