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 QString Info = QString(
"RA+ (%1, %2)").arg((cur_x - start_x1), 0,
'f', 1).arg((cur_y - start_y1), 0,
'f', 1);
203 addCalibrationUpdate(GuideInterface::RA_OUT, Info, 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 addCalibrationUpdate(GuideInterface::RA_OUT_OK, Info, cur_x - start_x1, cur_y - start_y1);
240 addPulse(RA_DEC_DIR, last_pulse);
243 addLogStatus(
i18n(
"RA drifting reverse..."));
245 guideLog->endCalibrationSection(RA_INC_DIR, tempCalibration.getAngle());
247 else if (ra_iterations > turn_back_time)
249 addLogStatus(
i18n(
"Calibration rejected. Star drift is too short. Check for mount, cable, or backlash problems."));
250 calibrationStage = CAL_ERROR;
251 addStatus(Ekos::GUIDE_CALIBRATION_ERROR);
252 addCalibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY,
i18n(
"Calibration Failed: Drift too short."));
254 guideLog->endCalibration(0, 0);
259 if (fabs(cur_x - last_x) < 0.5 && fabs(cur_y - last_y) < 0.5)
262 last_pulse = Options::calibrationPulseDuration() * 2;
266 ra_total_pulse += last_pulse;
267 last_pulse = Options::calibrationPulseDuration();
273 addPulse(RA_INC_DIR, last_pulse);
279void CalibrationProcess::raInState(
double cur_x,
double cur_y)
281 QString Info = QString(
"RA- (%1, %2)").arg((cur_x - start_x1), 0,
'f', 1).arg((cur_y - start_y1), 0,
'f', 1);
282 addCalibrationUpdate(GuideInterface::RA_IN, Info, cur_x - start_x1, cur_y - start_y1);
284 qCDebug(KSTARS_EKOS_GUIDE) <<
"Iteration #" << ra_iterations <<
": STAR " << cur_x <<
"," << cur_y;
285 qCDebug(KSTARS_EKOS_GUIDE) <<
"Iteration " << ra_iterations <<
" Direction: RA_DEC_DIR" <<
" Duration: "
286 << last_pulse <<
" ms.";
288 double driftRA, driftDEC;
289 tempCalibration.computeDrift(GuiderUtils::Vector(cur_x, cur_y, 0), GuiderUtils::Vector(start_x1, start_y1, 0),
290 &driftRA, &driftDEC);
292 qCDebug(KSTARS_EKOS_GUIDE) <<
"Star x pos is " << driftRA <<
" from original point.";
294 if (ra_distance == 0.0)
295 ra_distance = driftRA;
298 guideLog->addCalibrationData(RA_DEC_DIR, cur_x, cur_y, start_x1, start_y1);
303 last_pulse = Options::calibrationPulseDuration();
304 axisCalibrationComplete =
true;
308 else if ( (fabs(cur_x - last_x) < 0.5 && fabs(cur_y - last_y) < 0.5)
309 || driftRA > ra_distance)
315 last_pulse = Options::calibrationPulseDuration() * 2;
317 last_pulse = Options::calibrationPulseDuration();
322 last_pulse = Options::calibrationPulseDuration();
328 if (axisCalibrationComplete ==
false)
330 if (ra_iterations < turn_back_time)
332 addPulse(RA_DEC_DIR, last_pulse);
337 calibrationStage = CAL_ERROR;
338 addStatus(Ekos::GUIDE_CALIBRATION_ERROR);
339 addCalibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY,
i18n(
"Calibration Failed: couldn't reach start."));
340 addLogStatus(
i18np(
"Guide RA: Scope cannot reach the start point after %1 iteration. Possible mount or "
341 "backlash problems...",
342 "GUIDE_RA: Scope cannot reach the start point after %1 iterations. Possible mount or "
343 "backlash problems...",
350 if (Options::guideCalibrationBacklash())
352 calibrationStage = CAL_BACKLASH;
355 start_backlash_x = cur_x;
356 start_backlash_y = cur_y;
357 addPulse(DEC_INC_DIR, Options::calibrationPulseDuration());
358 backlash_iterations++;
359 addLogStatus(
i18n(
"DEC backlash..."));
363 calibrationStage = CAL_DEC_INC;
369 qCDebug(KSTARS_EKOS_GUIDE) <<
"Start X2 " << start_x2 <<
" start Y2 " << start_y2;
370 addPulse(DEC_INC_DIR, Options::calibrationPulseDuration());
372 addLogStatus(
i18n(
"DEC drifting forward..."));
377 if (calibration->calculate1D(start_x1, start_y1, end_x1, end_y1, ra_total_pulse))
380 calibrationStage = CAL_IDLE;
381 addStatus(Ekos::GUIDE_CALIBRATION_SUCCESS);
384 guideLog->endCalibration(1000.0 / calibration->raPulseMillisecondsPerArcsecond(), 0);
388 addLogStatus(
i18n(
"Calibration rejected. Star drift is too short. Check for mount, cable, or backlash problems."));
389 calibrationStage = CAL_ERROR;
390 addStatus(Ekos::GUIDE_CALIBRATION_ERROR);
391 addCalibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY,
i18n(
"Calibration Failed: drift too short."));
393 guideLog->endCalibration(0, 0);
397void CalibrationProcess::decBacklashState(
double cur_x,
double cur_y)
399 double driftRA, driftDEC;
400 tempCalibration.computeDrift(
401 GuiderUtils::Vector(cur_x, cur_y, 0),
402 GuiderUtils::Vector(start_backlash_x, start_backlash_y, 0),
403 &driftRA, &driftDEC);
407 constexpr int MIN_DEC_BACKLASH_MOVE_PIXELS = 3;
408 if ((++backlash_iterations >= 5) ||
409 (fabs(driftDEC) > MIN_DEC_BACKLASH_MOVE_PIXELS))
411 addCalibrationUpdate(GuideInterface::BACKLASH,
i18n(
"Calibrating DEC Backlash"),
412 cur_x - start_x1, cur_y - start_y1);
413 qCDebug(KSTARS_EKOS_GUIDE) << QString(
"Stopping dec backlash caibration after %1 iterations, offset %2")
414 .arg(backlash_iterations - 1)
415 .arg(driftDEC, 4,
'f', 2);
416 calibrationStage = CAL_DEC_INC;
422 qCDebug(KSTARS_EKOS_GUIDE) <<
"Start X2 " << start_x2 <<
" start Y2 " << start_y2;
423 addPulse(DEC_INC_DIR, Options::calibrationPulseDuration());
425 addLogStatus(
i18n(
"DEC drifting forward..."));
428 addCalibrationUpdate(GuideInterface::BACKLASH,
i18n(
"Calibrating DEC Backlash"),
429 cur_x - start_x1, cur_y - start_y1);
430 qCDebug(KSTARS_EKOS_GUIDE) <<
"Backlash iter" << backlash_iterations <<
"position" << cur_x << cur_y;
431 addPulse(DEC_INC_DIR, Options::calibrationPulseDuration());
435void CalibrationProcess::decOutState(
double cur_x,
double cur_y)
437 QString Info = QString(
"DE+ (%1, %2)").arg((cur_x - start_x1), 0,
'f', 1).arg((cur_y - start_y1), 0,
'f', 1);
438 addCalibrationUpdate(GuideInterface::DEC_OUT, Info, cur_x - start_x1, cur_y - start_y1);
440 qCDebug(KSTARS_EKOS_GUIDE) <<
"Iteration #" << dec_iterations <<
": STAR " << cur_x <<
"," << cur_y;
441 qCDebug(KSTARS_EKOS_GUIDE) <<
"Iteration " << dec_iterations <<
" Direction: DEC_INC_DIR" <<
442 " Duration: " << last_pulse <<
" ms.";
446 guideLog->addCalibrationData(DEC_INC_DIR, cur_x, cur_y,
448 const double xDrift = cur_x - start_x2;
449 const double yDrift = cur_y - start_y2;
450 if (((dec_iterations >= maximumSteps) ||
451 (std::hypot(xDrift, yDrift) > Options::calibrationMaxMove()))
452 && (fabs(xDrift) > 1.5 || fabs(yDrift) > 1.5))
454 calibrationStage = CAL_DEC_DEC;
456 de_total_pulse += last_pulse;
464 axisCalibrationComplete =
false;
466 qCDebug(KSTARS_EKOS_GUIDE) <<
"End X2 " << end_x2 <<
" End Y2 " << end_y2;
468 tempCalibration.calculate1D(start_x2, start_y2, end_x2, end_y2, de_total_pulse);
472 addCalibrationUpdate(GuideInterface::DEC_OUT_OK, Info, cur_x - start_x1, cur_y - start_y1);
474 addPulse(DEC_DEC_DIR, last_pulse);
475 addLogStatus(
i18n(
"DEC drifting reverse..."));
478 guideLog->endCalibrationSection(DEC_INC_DIR, tempCalibration.getAngle());
480 else if (dec_iterations > turn_back_time)
482 calibrationStage = CAL_ERROR;
484 addStatus(Ekos::GUIDE_CALIBRATION_ERROR);
485 addCalibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY,
i18n(
"Calibration Failed: couldn't reach start point."));
486 addLogStatus(
i18np(
"Guide DEC: Scope cannot reach the start point after %1 iteration.\nPossible mount "
487 "or backlash problems...",
488 "GUIDE DEC: Scope cannot reach the start point after %1 iterations.\nPossible mount "
489 "or backlash problems...",
493 guideLog->endCalibration(0, 0);
497 if (fabs(cur_x - last_x) < 0.5 && fabs(cur_y - last_y) < 0.5)
500 last_pulse = Options::calibrationPulseDuration() * 2;
504 de_total_pulse += last_pulse;
505 last_pulse = Options::calibrationPulseDuration();
510 addPulse(DEC_INC_DIR, last_pulse);
516void CalibrationProcess::decInState(
double cur_x,
double cur_y)
518 QString Info = QString(
"DE- (%1, %2)").arg((cur_x - start_x1), 0,
'f', 1).arg((cur_y - start_y1), 0,
'f', 1);
519 addCalibrationUpdate(GuideInterface::DEC_IN, Info, cur_x - start_x1, cur_y - start_y1);
522 qCDebug(KSTARS_EKOS_GUIDE) <<
"Iteration #" << dec_iterations <<
": STAR " << cur_x <<
"," << cur_y;
523 qCDebug(KSTARS_EKOS_GUIDE) <<
"Iteration " << dec_iterations <<
" Direction: DEC_DEC_DIR" <<
524 " Duration: " << last_pulse <<
" ms.";
528 double driftRA, driftDEC;
529 tempCalibration.computeDrift(
530 GuiderUtils::Vector(cur_x, cur_y, 0),
531 GuiderUtils::Vector(start_x1, start_y1, 0),
532 &driftRA, &driftDEC);
534 qCDebug(KSTARS_EKOS_GUIDE) <<
"Currently " << driftRA << driftDEC <<
" from original point.";
537 if (de_distance == 0.0)
538 de_distance = driftRA;
541 guideLog->addCalibrationData(DEC_DEC_DIR, cur_x, cur_y, start_x2, start_y2);
546 last_pulse = Options::calibrationPulseDuration();
547 axisCalibrationComplete =
true;
550 else if ( (fabs(cur_x - last_x) < 0.5 && fabs(cur_y - last_y) < 0.5)
551 || driftRA > de_distance)
554 last_pulse = Options::calibrationPulseDuration() * 2;
558 last_pulse = Options::calibrationPulseDuration();
561 if (axisCalibrationComplete ==
false)
563 if (dec_iterations < turn_back_time)
565 addPulse(DEC_DEC_DIR, last_pulse);
570 calibrationStage = CAL_ERROR;
572 addStatus(Ekos::GUIDE_CALIBRATION_ERROR);
573 addCalibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY,
i18n(
"Calibration Failed: couldn't reach start point."));
575 addLogStatus(
i18np(
"Guide DEC: Scope cannot reach the start point after %1 iteration.\nPossible mount "
576 "or backlash problems...",
577 "Guide DEC: Scope cannot reach the start point after %1 iterations.\nPossible mount "
578 "or backlash problems...",
583 bool reverse_dec_dir =
false;
585 if (calibration->calculate2D(start_x1, start_y1, end_x1, end_y1, start_x2, start_y2, end_x2, end_y2,
586 &reverse_dec_dir, ra_total_pulse, de_total_pulse))
588 double rotation = calibration->getAngle();
589 QString success = QString(
"Calibration OK\n Rotation = %1").arg(rotation, 0,
'f', 1);
590 addCalibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY,
i18n(success.
toLatin1().
data()));
593 calibrationStage = CAL_IDLE;
595 addLogStatus(
i18n(
"DEC direction reversed (RA-DEC is now standard CCW-system)."));
597 addStatus(Ekos::GUIDE_CALIBRATION_SUCCESS);
601 guideLog->endCalibration(
602 1000.0 / calibration->raPulseMillisecondsPerArcsecond(),
603 1000.0 / calibration->decPulseMillisecondsPerArcsecond());
608 addLogStatus(
i18n(
"Calibration rejected. Star drift is too short. Check for mount, cable, or backlash problems."));
609 addCalibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY,
i18n(
"Calibration Failed: drift too short."));
610 addStatus(Ekos::GUIDE_CALIBRATION_ERROR);
611 calibrationStage = CAL_ERROR;
613 guideLog->endCalibration(0, 0);
QString i18np(const char *singular, const char *plural, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
Type type(const QSqlDatabase &db)
Ekos is an advanced Astrophotography tool for Linux.
KIOCORE_EXPORT QString dir(const QString &fileClass)
QByteArray toLatin1() const const