File indexing completed on 2024-05-12 15:23:40

0001 #include "calibrationprocess.h"
0002 
0003 #include "gmath.h"
0004 #include "ekos_guide_debug.h"
0005 #include "gmath.h"
0006 #include "guidelog.h"
0007 
0008 #include "Options.h"
0009 
0010 namespace Ekos
0011 {
0012 
0013 QString stageString(Ekos::CalibrationProcess::CalibrationStage stage)
0014 {
0015     switch(stage)
0016     {
0017         case Ekos::CalibrationProcess::CAL_IDLE:
0018             return ("CAL_IDLE");
0019         case Ekos::CalibrationProcess::CAL_ERROR:
0020             return("CAL_ERROR");
0021         case Ekos::CalibrationProcess::CAL_CAPTURE_IMAGE:
0022             return("CAL_CAPTURE_IMAGE");
0023         case Ekos::CalibrationProcess::CAL_SELECT_STAR:
0024             return("CAL_SELECT_STAR");
0025         case Ekos::CalibrationProcess::CAL_START:
0026             return("CAL_START");
0027         case Ekos::CalibrationProcess::CAL_RA_INC:
0028             return("CAL_RA_INC");
0029         case Ekos::CalibrationProcess::CAL_RA_DEC:
0030             return("CAL_RA_DEC");
0031         case Ekos::CalibrationProcess::CAL_DEC_INC:
0032             return("CAL_DEC_INC");
0033         case Ekos::CalibrationProcess::CAL_DEC_DEC:
0034             return("CAL_DEC_DEC");
0035         case Ekos::CalibrationProcess::CAL_BACKLASH:
0036             return("CAL_BACKLASH");
0037         default:
0038             return("???");
0039     };
0040 }
0041 
0042 CalibrationProcess::CalibrationProcess(double startX, double startY, bool raOnlyEnabled)
0043 {
0044     calibrationStage = CAL_START;
0045     raOnly = raOnlyEnabled;
0046     start_x1 = startX;
0047     start_y1 = startY;
0048 }
0049 
0050 void CalibrationProcess::useCalibration(Calibration *calibrationPtr)
0051 {
0052     calibration = calibrationPtr;
0053     tempCalibration = *calibration;
0054 }
0055 
0056 void CalibrationProcess::startup()
0057 {
0058     calibrationStage = CAL_START;
0059 }
0060 
0061 void CalibrationProcess::setGuideLog(GuideLog *guideLogPtr)
0062 {
0063     guideLog = guideLogPtr;
0064 }
0065 
0066 bool CalibrationProcess::inProgress() const
0067 {
0068     return calibrationStage > CAL_START;
0069 }
0070 
0071 void CalibrationProcess::addCalibrationUpdate(
0072     GuideInterface::CalibrationUpdateType type,
0073     QString message, double x, double y)
0074 {
0075     updateType = type;
0076     calibrationUpdate = message;
0077     updateX = x;
0078     updateY = y;
0079 }
0080 
0081 void CalibrationProcess::getCalibrationUpdate(
0082     GuideInterface::CalibrationUpdateType *type,
0083     QString *message, double *x, double *y) const
0084 {
0085     *type = updateType;
0086     *message = calibrationUpdate;
0087     *x = updateX;
0088     *y = updateY;
0089 }
0090 
0091 QString CalibrationProcess::getLogStatus() const
0092 {
0093     return logString;
0094 }
0095 
0096 void CalibrationProcess::addLogStatus(const QString &message)
0097 {
0098     logString = message;
0099 }
0100 
0101 void CalibrationProcess::addPulse(GuideDirection dir, int msecs)
0102 {
0103     pulseDirection = dir;
0104     pulseMsecs = msecs;
0105 }
0106 
0107 void CalibrationProcess::getPulse(GuideDirection *dir, int *msecs) const
0108 {
0109     *dir = pulseDirection;
0110     *msecs = pulseMsecs;
0111 }
0112 
0113 void CalibrationProcess::addStatus(Ekos::GuideState s)
0114 {
0115     status = s;
0116 }
0117 
0118 Ekos::GuideState CalibrationProcess::getStatus() const
0119 {
0120     return status;
0121 }
0122 
0123 void CalibrationProcess::initializeIteration()
0124 {
0125     axisCalibrationComplete = false;
0126 
0127     logString.clear();
0128 
0129     calibrationUpdate.clear();
0130     updateType = GuideInterface::CALIBRATION_MESSAGE_ONLY;
0131     updateX = 0;
0132     updateY = 0;
0133 
0134     addStatus(Ekos::GUIDE_CALIBRATING);
0135 
0136     pulseDirection = NO_DIR;
0137     pulseMsecs = 0;
0138 }
0139 
0140 void CalibrationProcess::iterate(double x, double y)
0141 {
0142     initializeIteration();
0143     switch (calibrationStage)
0144     {
0145         case CAL_START:
0146             startState();
0147             break;
0148         case CAL_RA_INC:
0149             raOutState(x, y);
0150             break;
0151         case CAL_RA_DEC:
0152             raInState(x, y);
0153             break;
0154         case CAL_BACKLASH:
0155             decBacklashState(x, y);
0156             break;
0157         case CAL_DEC_INC:
0158             decOutState(x, y);
0159             break;
0160         case CAL_DEC_DEC:
0161             decInState(x, y);
0162             break;
0163         default:
0164             break;
0165     }
0166 }
0167 
0168 void CalibrationProcess::startState()
0169 {
0170     maximumSteps = Options::autoModeIterations();
0171     turn_back_time = maximumSteps * 7;
0172 
0173     ra_iterations = 0;
0174     dec_iterations = 0;
0175     backlash_iterations = 0;
0176     ra_total_pulse = de_total_pulse = 0;
0177 
0178     addLogStatus(i18n("RA drifting forward..."));
0179 
0180     last_pulse = Options::calibrationPulseDuration();
0181 
0182     addCalibrationUpdate(GuideInterface::RA_OUT, i18n("Guide Star found."), 0, 0);
0183 
0184     qCDebug(KSTARS_EKOS_GUIDE) << "Auto Iteration #" << maximumSteps << "Default pulse:" << last_pulse;
0185     qCDebug(KSTARS_EKOS_GUIDE) << "Start X1 " << start_x1 << " Start Y1 " << start_y1;
0186 
0187     last_x = start_x1;
0188     last_y = start_x2;
0189 
0190     addPulse(RA_INC_DIR, last_pulse);
0191 
0192     ra_iterations++;
0193 
0194     calibrationStage = CAL_RA_INC;
0195     if (guideLog)
0196         guideLog->addCalibrationData(RA_INC_DIR, start_x1, start_y1, start_x1, start_y1);
0197 }
0198 
0199 
0200 void CalibrationProcess::raOutState(double cur_x, double cur_y)
0201 {
0202     addCalibrationUpdate(GuideInterface::RA_OUT, i18n("Calibrating RA Out"),
0203                          cur_x - start_x1, cur_y - start_y1);
0204 
0205     qCDebug(KSTARS_EKOS_GUIDE) << "Iteration #" << ra_iterations << ": STAR " << cur_x << "," << cur_y;
0206     qCDebug(KSTARS_EKOS_GUIDE) << "Iteration " << ra_iterations << " Direction: RA_INC_DIR" << " Duration: "
0207                                << last_pulse << " ms.";
0208 
0209     if (guideLog)
0210         guideLog->addCalibrationData(RA_INC_DIR, cur_x, cur_y, start_x1, start_y1);
0211 
0212     // Must pass at least 1.5 pixels to move on to the next stage.
0213     // If we've moved 15 pixels, we can cut short the requested number of iterations.
0214     const double xDrift = cur_x - start_x1;
0215     const double yDrift = cur_y - start_y1;
0216     if (((ra_iterations >= maximumSteps) ||
0217             (std::hypot(xDrift, yDrift) > Options::calibrationMaxMove()))
0218             && (fabs(xDrift) > 1.5 || fabs(yDrift) > 1.5))
0219     {
0220         ra_total_pulse += last_pulse;
0221         calibrationStage = CAL_RA_DEC;
0222 
0223         end_x1 = cur_x;
0224         end_y1 = cur_y;
0225 
0226         last_x = cur_x;
0227         last_y = cur_y;
0228 
0229         qCDebug(KSTARS_EKOS_GUIDE) << "End X1 " << end_x1 << " End Y1 " << end_y1;
0230 
0231         // This temporary calibration is just used to help find our way back to the origin.
0232         // total_pulse is not used, but valid.
0233         tempCalibration.calculate1D(start_x1, start_y1, end_x1, end_y1, ra_total_pulse);
0234 
0235         ra_distance = 0;
0236         backlash = 0;
0237 
0238         addPulse(RA_DEC_DIR, last_pulse);
0239         ra_iterations++;
0240 
0241         addLogStatus(i18n("RA drifting reverse..."));
0242         if (guideLog)
0243             guideLog->endCalibrationSection(RA_INC_DIR, tempCalibration.getAngle());
0244     }
0245     else if (ra_iterations > turn_back_time)
0246     {
0247         addLogStatus(i18n("Calibration rejected. Star drift is too short. Check for mount, cable, or backlash problems."));
0248         calibrationStage = CAL_ERROR;
0249         addStatus(Ekos::GUIDE_CALIBRATION_ERROR);
0250         addCalibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY, i18n("Calibration Failed: Drift too short."));
0251         if (guideLog)
0252             guideLog->endCalibration(0, 0);
0253     }
0254     else
0255     {
0256         // Aggressive pulse in case we're going slow
0257         if (fabs(cur_x - last_x) < 0.5 && fabs(cur_y - last_y) < 0.5)
0258         {
0259             // 200%
0260             last_pulse = Options::calibrationPulseDuration() * 2;
0261         }
0262         else
0263         {
0264             ra_total_pulse += last_pulse;
0265             last_pulse = Options::calibrationPulseDuration();
0266         }
0267 
0268         last_x = cur_x;
0269         last_y = cur_y;
0270 
0271         addPulse(RA_INC_DIR, last_pulse);
0272 
0273         ra_iterations++;
0274     }
0275 }
0276 
0277 void CalibrationProcess::raInState(double cur_x, double cur_y)
0278 {
0279     addCalibrationUpdate(GuideInterface::RA_IN, i18n("Calibrating RA In"),
0280                          cur_x - start_x1, cur_y - start_y1);
0281     qCDebug(KSTARS_EKOS_GUIDE) << "Iteration #" << ra_iterations << ": STAR " << cur_x << "," << cur_y;
0282     qCDebug(KSTARS_EKOS_GUIDE) << "Iteration " << ra_iterations << " Direction: RA_DEC_DIR" << " Duration: "
0283                                << last_pulse << " ms.";
0284 
0285     double driftRA, driftDEC;
0286     tempCalibration.computeDrift(GuiderUtils::Vector(cur_x, cur_y, 0), GuiderUtils::Vector(start_x1, start_y1, 0),
0287                                  &driftRA, &driftDEC);
0288 
0289     qCDebug(KSTARS_EKOS_GUIDE) << "Star x pos is " << driftRA << " from original point.";
0290 
0291     if (ra_distance == 0.0)
0292         ra_distance = driftRA;
0293 
0294     if (guideLog)
0295         guideLog->addCalibrationData(RA_DEC_DIR, cur_x, cur_y, start_x1, start_y1);
0296 
0297     // start point reached... so exit
0298     if (driftRA < 1.5)
0299     {
0300         last_pulse = Options::calibrationPulseDuration();
0301         axisCalibrationComplete = true;
0302     }
0303     // If we'not moving much, try increasing pulse to 200% to clear any backlash
0304     // Also increase pulse width if we are going FARTHER and not back to our original position
0305     else if ( (fabs(cur_x - last_x) < 0.5 && fabs(cur_y - last_y) < 0.5)
0306               || driftRA > ra_distance)
0307     {
0308         backlash++;
0309 
0310         // Increase pulse to 200% after we tried to fight against backlash 2 times at least
0311         if (backlash > 2)
0312             last_pulse = Options::calibrationPulseDuration() * 2;
0313         else
0314             last_pulse = Options::calibrationPulseDuration();
0315     }
0316     else
0317     {
0318         //ra_total_pulse += last_pulse;
0319         last_pulse = Options::calibrationPulseDuration();
0320         backlash = 0;
0321     }
0322     last_x = cur_x;
0323     last_y = cur_y;
0324 
0325     if (axisCalibrationComplete == false)
0326     {
0327         if (ra_iterations < turn_back_time)
0328         {
0329             addPulse(RA_DEC_DIR, last_pulse);
0330             ra_iterations++;
0331             return;
0332         }
0333 
0334         calibrationStage = CAL_ERROR;
0335         addStatus(Ekos::GUIDE_CALIBRATION_ERROR);
0336         addCalibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY, i18n("Calibration Failed: couldn't reach start."));
0337         addLogStatus(i18np("Guide RA: Scope cannot reach the start point after %1 iteration. Possible mount or "
0338                            "backlash problems...",
0339                            "GUIDE_RA: Scope cannot reach the start point after %1 iterations. Possible mount or "
0340                            "backlash problems...",
0341                            ra_iterations));
0342         return;
0343     }
0344 
0345     if (raOnly == false)
0346     {
0347         if (Options::guideCalibrationBacklash())
0348         {
0349             calibrationStage = CAL_BACKLASH;
0350             last_x = cur_x;
0351             last_y = cur_y;
0352             start_backlash_x = cur_x;
0353             start_backlash_y = cur_y;
0354             addPulse(DEC_INC_DIR, Options::calibrationPulseDuration());
0355             backlash_iterations++;
0356             addLogStatus(i18n("DEC backlash..."));
0357         }
0358         else
0359         {
0360             calibrationStage = CAL_DEC_INC;
0361             start_x2         = cur_x;
0362             start_y2         = cur_y;
0363             last_x = cur_x;
0364             last_y = cur_y;
0365 
0366             qCDebug(KSTARS_EKOS_GUIDE) << "Start X2 " << start_x2 << " start Y2 " << start_y2;
0367             addPulse(DEC_INC_DIR, Options::calibrationPulseDuration());
0368             dec_iterations++;
0369             addLogStatus(i18n("DEC drifting forward..."));
0370         }
0371         return;
0372     }
0373     // calc orientation
0374     if (calibration->calculate1D(start_x1, start_y1, end_x1, end_y1, ra_total_pulse))
0375     {
0376         calibration->save();
0377         calibrationStage = CAL_IDLE;
0378         addStatus(Ekos::GUIDE_CALIBRATION_SUCCESS);
0379         // Below converts from ms/arcsecond to arcseconds/second.
0380         if (guideLog)
0381             guideLog->endCalibration(1000.0 / calibration->raPulseMillisecondsPerArcsecond(), 0);
0382     }
0383     else
0384     {
0385         addLogStatus(i18n("Calibration rejected. Star drift is too short. Check for mount, cable, or backlash problems."));
0386         calibrationStage = CAL_ERROR;
0387         addStatus(Ekos::GUIDE_CALIBRATION_ERROR);
0388         addCalibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY, i18n("Calibration Failed: drift too short."));
0389         if (guideLog)
0390             guideLog->endCalibration(0, 0);
0391     }
0392 }
0393 
0394 void CalibrationProcess::decBacklashState(double cur_x, double cur_y)
0395 {
0396     double driftRA, driftDEC;
0397     tempCalibration.computeDrift(
0398         GuiderUtils::Vector(cur_x, cur_y, 0),
0399         GuiderUtils::Vector(start_backlash_x, start_backlash_y, 0),
0400         &driftRA, &driftDEC);
0401 
0402     // Exit the backlash phase either after 5 pulses, or after we've moved sufficiently in the
0403     // DEC direction.
0404     constexpr int MIN_DEC_BACKLASH_MOVE_PIXELS = 3;
0405     if ((++backlash_iterations >= 5) ||
0406             (fabs(driftDEC) > MIN_DEC_BACKLASH_MOVE_PIXELS))
0407     {
0408         addCalibrationUpdate(GuideInterface::BACKLASH, i18n("Calibrating DEC Backlash"),
0409                              cur_x - start_x1, cur_y - start_y1);
0410         qCDebug(KSTARS_EKOS_GUIDE) << QString("Stopping dec backlash caibration after %1 iterations, offset %2")
0411                                    .arg(backlash_iterations - 1)
0412                                    .arg(driftDEC, 4, 'f', 2);
0413         calibrationStage = CAL_DEC_INC;
0414         start_x2         = cur_x;
0415         start_y2         = cur_y;
0416         last_x = cur_x;
0417         last_y = cur_y;
0418 
0419         qCDebug(KSTARS_EKOS_GUIDE) << "Start X2 " << start_x2 << " start Y2 " << start_y2;
0420         addPulse(DEC_INC_DIR, Options::calibrationPulseDuration());
0421         dec_iterations++;
0422         addLogStatus(i18n("DEC drifting forward..."));
0423         return;
0424     }
0425     addCalibrationUpdate(GuideInterface::BACKLASH, i18n("Calibrating DEC Backlash"),
0426                          cur_x - start_x1, cur_y - start_y1);
0427     qCDebug(KSTARS_EKOS_GUIDE) << "Backlash iter" << backlash_iterations << "position" << cur_x << cur_y;
0428     addPulse(DEC_INC_DIR, Options::calibrationPulseDuration());
0429 }
0430 
0431 
0432 void CalibrationProcess::decOutState(double cur_x, double cur_y)
0433 {
0434     addCalibrationUpdate(GuideInterface::DEC_OUT, i18n("Calibrating DEC Out"),
0435                          cur_x - start_x1, cur_y - start_y1);
0436 
0437     qCDebug(KSTARS_EKOS_GUIDE) << "Iteration #" << dec_iterations << ": STAR " << cur_x << "," << cur_y;
0438     qCDebug(KSTARS_EKOS_GUIDE) << "Iteration " << dec_iterations << " Direction: DEC_INC_DIR" <<
0439                                " Duration: " << last_pulse << " ms.";
0440 
0441     // Don't yet know how to tell NORTH vs SOUTH
0442     if (guideLog)
0443         guideLog->addCalibrationData(DEC_INC_DIR, cur_x, cur_y,
0444                                      start_x2, start_y2);
0445     const double xDrift = cur_x - start_x2;
0446     const double yDrift = cur_y - start_y2;
0447     if (((dec_iterations >= maximumSteps) ||
0448             (std::hypot(xDrift, yDrift) > Options::calibrationMaxMove()))
0449             && (fabs(xDrift) > 1.5 || fabs(yDrift) > 1.5))
0450     {
0451         calibrationStage = CAL_DEC_DEC;
0452 
0453         de_total_pulse += last_pulse;
0454 
0455         end_x2 = cur_x;
0456         end_y2 = cur_y;
0457 
0458         last_x = cur_x;
0459         last_y = cur_y;
0460 
0461         axisCalibrationComplete = false;
0462 
0463         qCDebug(KSTARS_EKOS_GUIDE) << "End X2 " << end_x2 << " End Y2 " << end_y2;
0464 
0465         tempCalibration.calculate1D(start_x2, start_y2, end_x2, end_y2, de_total_pulse);
0466 
0467         de_distance = 0;
0468 
0469         addPulse(DEC_DEC_DIR, last_pulse);
0470         addLogStatus(i18n("DEC drifting reverse..."));
0471         dec_iterations++;
0472         if (guideLog)
0473             guideLog->endCalibrationSection(DEC_INC_DIR, tempCalibration.getAngle());
0474     }
0475     else if (dec_iterations > turn_back_time)
0476     {
0477         calibrationStage = CAL_ERROR;
0478 
0479         addStatus(Ekos::GUIDE_CALIBRATION_ERROR);
0480         addCalibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY, i18n("Calibration Failed: couldn't reach start point."));
0481         addLogStatus(i18np("Guide DEC: Scope cannot reach the start point after %1 iteration.\nPossible mount "
0482                            "or backlash problems...",
0483                            "GUIDE DEC: Scope cannot reach the start point after %1 iterations.\nPossible mount "
0484                            "or backlash problems...",
0485                            dec_iterations));
0486 
0487         if (guideLog)
0488             guideLog->endCalibration(0, 0);
0489     }
0490     else
0491     {
0492         if (fabs(cur_x - last_x) < 0.5 && fabs(cur_y - last_y) < 0.5)
0493         {
0494             // Increase pulse by 200%
0495             last_pulse = Options::calibrationPulseDuration() * 2;
0496         }
0497         else
0498         {
0499             de_total_pulse += last_pulse;
0500             last_pulse = Options::calibrationPulseDuration();
0501         }
0502         last_x = cur_x;
0503         last_y = cur_y;
0504 
0505         addPulse(DEC_INC_DIR, last_pulse);
0506 
0507         dec_iterations++;
0508     }
0509 }
0510 
0511 void CalibrationProcess::decInState(double cur_x, double cur_y)
0512 {
0513     addCalibrationUpdate(GuideInterface::DEC_IN, i18n("Calibrating DEC In"),
0514                          cur_x - start_x1, cur_y - start_y1);
0515 
0516     // Star position resulting from LAST guiding pulse to mount
0517     qCDebug(KSTARS_EKOS_GUIDE) << "Iteration #" << dec_iterations << ": STAR " << cur_x << "," << cur_y;
0518     qCDebug(KSTARS_EKOS_GUIDE) << "Iteration " << dec_iterations << " Direction: DEC_DEC_DIR" <<
0519                                " Duration: " << last_pulse << " ms.";
0520 
0521     // Note: the way this temp calibration was set up above, with the DEC drifts, the ra axis is really dec.
0522     // This will help the dec find its way home. Could convert to a full RA/DEC calibration.
0523     double driftRA, driftDEC;
0524     tempCalibration.computeDrift(
0525         GuiderUtils::Vector(cur_x, cur_y, 0),
0526         GuiderUtils::Vector(start_x1, start_y1, 0),
0527         &driftRA, &driftDEC);
0528 
0529     qCDebug(KSTARS_EKOS_GUIDE) << "Currently " << driftRA << driftDEC << " from original point.";
0530 
0531     // Keep track of distance
0532     if (de_distance == 0.0)
0533         de_distance = driftRA;
0534 
0535     if (guideLog)
0536         guideLog->addCalibrationData(DEC_DEC_DIR, cur_x, cur_y, start_x2, start_y2);
0537 
0538     // start point reached... so exit
0539     if (driftRA < 1.5)
0540     {
0541         last_pulse = Options::calibrationPulseDuration();
0542         axisCalibrationComplete = true;
0543     }
0544     // Increase pulse if we're not moving much or if we are moving _away_ from target.
0545     else if ( (fabs(cur_x - last_x) < 0.5 && fabs(cur_y - last_y) < 0.5)
0546               || driftRA > de_distance)
0547     {
0548         // Increase pulse by 200%
0549         last_pulse = Options::calibrationPulseDuration() * 2;
0550     }
0551     else
0552     {
0553         last_pulse = Options::calibrationPulseDuration();
0554     }
0555 
0556     if (axisCalibrationComplete == false)
0557     {
0558         if (dec_iterations < turn_back_time)
0559         {
0560             addPulse(DEC_DEC_DIR, last_pulse);
0561             dec_iterations++;
0562             return;
0563         }
0564 
0565         calibrationStage = CAL_ERROR;
0566 
0567         addStatus(Ekos::GUIDE_CALIBRATION_ERROR);
0568         addCalibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY, i18n("Calibration Failed: couldn't reach start point."));
0569 
0570         addLogStatus(i18np("Guide DEC: Scope cannot reach the start point after %1 iteration.\nPossible mount "
0571                            "or backlash problems...",
0572                            "Guide DEC: Scope cannot reach the start point after %1 iterations.\nPossible mount "
0573                            "or backlash problems...",
0574                            dec_iterations));
0575         return;
0576     }
0577 
0578     bool swap_dec = false;
0579     // calc orientation
0580     if (calibration->calculate2D(start_x1, start_y1, end_x1, end_y1, start_x2, start_y2, end_x2, end_y2,
0581                                  &swap_dec, ra_total_pulse, de_total_pulse))
0582     {
0583         calibration->save();
0584         calibrationStage = CAL_IDLE;
0585         if (swap_dec)
0586             addLogStatus(i18n("DEC swap enabled."));
0587         else
0588             addLogStatus(i18n("DEC swap disabled."));
0589 
0590         addStatus(Ekos::GUIDE_CALIBRATION_SUCCESS);
0591 
0592         addCalibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY, i18n("Calibration Successful"));
0593 
0594         // Below converts from ms/arcsecond to arcseconds/second.
0595         if (guideLog)
0596             guideLog->endCalibration(
0597                 1000.0 / calibration->raPulseMillisecondsPerArcsecond(),
0598                 1000.0 / calibration->decPulseMillisecondsPerArcsecond());
0599         return;
0600     }
0601     else
0602     {
0603         addLogStatus(i18n("Calibration rejected. Star drift is too short. Check for mount, cable, or backlash problems."));
0604         addCalibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY, i18n("Calibration Failed: drift too short."));
0605         addStatus(Ekos::GUIDE_CALIBRATION_ERROR);
0606         calibrationStage = CAL_ERROR;
0607         if (guideLog)
0608             guideLog->endCalibration(0, 0);
0609         return;
0610     }
0611 }
0612 
0613 }  // namespace Ekos