File indexing completed on 2024-04-28 15:09:02

0001 /*
0002     SPDX-FileCopyrightText: 2016 Jasem Mutlaq <mutlaqja@ikarustech.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "astapastrometryparser.h"
0008 
0009 #include "align.h"
0010 #include "ekos_align_debug.h"
0011 #include "Options.h"
0012 #include "indi/clientmanager.h"
0013 #include "indi/driverinfo.h"
0014 #include "indi/guimanager.h"
0015 #include "indi/indidevice.h"
0016 
0017 #include <indicom.h>
0018 
0019 #include <KMessageBox>
0020 
0021 namespace Ekos
0022 {
0023 ASTAPAstrometryParser::ASTAPAstrometryParser() : AstrometryParser()
0024 {
0025 }
0026 
0027 bool ASTAPAstrometryParser::init()
0028 {
0029     return QFile::exists(Options::aSTAPExecutable());
0030 }
0031 
0032 void ASTAPAstrometryParser::verifyIndexFiles(double, double)
0033 {
0034 }
0035 
0036 bool ASTAPAstrometryParser::startSolver(const QString &filename, const QStringList &args, bool generated)
0037 {
0038     INDI_UNUSED(generated);
0039 
0040     QStringList solverArgs = args;
0041 
0042     solverArgs << "-f" << filename;
0043 
0044     QString solutionFile = QDir::tempPath() + "/solution";
0045     solverArgs << "-o" << solutionFile;
0046 
0047     solver.clear();
0048     solver = new QProcess(this);
0049 
0050     connect(solver, static_cast<void (QProcess::*)(int exitCode, QProcess::ExitStatus exitStatus)>(&QProcess::finished),
0051             this, &ASTAPAstrometryParser::solverComplete);
0052     //    solver->setProcessChannelMode(QProcess::MergedChannels);
0053     //    connect(solver, SIGNAL(readyReadStandardOutput()), this, SLOT(logSolver()));
0054 #if QT_VERSION > QT_VERSION_CHECK(5, 6, 0)
0055     connect(solver.data(), &QProcess::errorOccurred, this, [&]()
0056     {
0057         align->appendLogText(i18n("Error starting solver: %1", solver->errorString()));
0058         emit solverFailed();
0059     });
0060 #else
0061     connect(solver, SIGNAL(error(QProcess::ProcessError)), this, SIGNAL(solverFailed()));
0062 #endif
0063 
0064     solverTimer.start();
0065 
0066     QString solverPath = Options::aSTAPExecutable();
0067 
0068     solver->start(solverPath, solverArgs);
0069 
0070     align->appendLogText(i18n("Starting solver..."));
0071 
0072     if (Options::alignmentLogging())
0073     {
0074         QString command = solverPath + ' ' + solverArgs.join(' ');
0075         align->appendLogText(command);
0076     }
0077 
0078     return true;
0079 }
0080 
0081 void ASTAPAstrometryParser::solverComplete(int exitCode, QProcess::ExitStatus exitStatus)
0082 {
0083     Q_UNUSED(exitCode)
0084     Q_UNUSED(exitStatus)
0085 
0086     QFile solution(QDir::tempPath() + "/solution.ini");
0087 
0088     if (!solution.open(QIODevice::ReadOnly))
0089     {
0090         qCritical(KSTARS_EKOS_ALIGN) << "Failed to open solution file" << QDir::tempPath() + "/solution.ini";
0091         emit solverFailed();
0092         return;
0093     }
0094 
0095     QTextStream in(&solution);
0096     QString line = in.readLine();
0097 
0098     QStringList ini = line.split("=");
0099     if (ini.count() <= 1 || ini[1] == "F")
0100     {
0101         align->appendLogText(i18n("Solver failed. Try again."));
0102         emit solverFailed();
0103         return;
0104     }
0105 
0106     double ra = 0, dec = 0, orientation = 0, pixscale = 0;
0107     double cd11 = 0;
0108     double cd22 = 0;
0109     double cd12 = 0;
0110     double cd21 = 0;
0111     bool ok[8] = {false};
0112 
0113     line = in.readLine();
0114     while (!line.isNull())
0115     {
0116         QStringList ini = line.split("=");
0117         if (ini[0] == "CRVAL1")
0118             ra = ini[1].trimmed().toDouble(&ok[0]);
0119         else if (ini[0] == "CRVAL2")
0120             dec = ini[1].trimmed().toDouble(&ok[1]);
0121         else if (ini[0] == "CDELT1")
0122             pixscale = ini[1].trimmed().toDouble(&ok[2]) * 3600.0;
0123         else if (ini[0] == "CROTA1")
0124             orientation = ini[1].trimmed().toDouble(&ok[3]);
0125         else if (ini[0] == "CD1_1")
0126             cd11 = ini[1].trimmed().toDouble(&ok[4]);
0127         else if (ini[0] == "CD1_2")
0128             cd12 = ini[1].trimmed().toDouble(&ok[5]);
0129         else if (ini[0] == "CD2_1")
0130             cd21 = ini[1].trimmed().toDouble(&ok[6]);
0131         else if (ini[0] == "CD2_2")
0132             cd22 = ini[1].trimmed().toDouble(&ok[7]);
0133 
0134         line = in.readLine();
0135     }
0136 
0137     if ( ok[0] && ok[1] && ok[2] && ok[3] )
0138     {
0139         Bool eastToTheRight = true;
0140         if ( ok[4] && ok[5] && ok[6] && ok[7] )
0141         {
0142             // Negative determinant = positive parity (i.e. east on the left).
0143             double det = cd11 * cd22 - cd12 * cd21;
0144             if(det < 0)
0145                 eastToTheRight = false;
0146         }
0147         int elapsed = static_cast<int>(round(solverTimer.elapsed() / 1000.0));
0148         align->appendLogText(i18np("Solver completed in %1 second.", "Solver completed in %1 seconds.", elapsed));
0149         emit solverFinished(orientation, ra, dec, pixscale, eastToTheRight);
0150     }
0151     else
0152     {
0153         align->appendLogText(i18n("Solver failed. Try again."));
0154         emit solverFailed();
0155     }
0156 }
0157 
0158 bool ASTAPAstrometryParser::stopSolver()
0159 {
0160     if (solver.isNull() == false)
0161     {
0162         solver->terminate();
0163         solver->disconnect();
0164     }
0165 
0166     return true;
0167 }
0168 }