diff --git a/kstars/CMakeLists.txt b/kstars/CMakeLists.txt --- a/kstars/CMakeLists.txt +++ b/kstars/CMakeLists.txt @@ -207,6 +207,7 @@ #ekos/guide/internalguide/rcalibration.cpp ekos/guide/internalguide/vect.cpp ekos/guide/internalguide/imageautoguiding.cpp + ekos/guide/internalguide/guidelog.cpp # External Guide ekos/guide/externalguide/phd2.cpp ekos/guide/externalguide/linguider.cpp diff --git a/kstars/ekos/guide/guide.h b/kstars/ekos/guide/guide.h --- a/kstars/ekos/guide/guide.h +++ b/kstars/ekos/guide/guide.h @@ -375,6 +375,8 @@ void setCaptureStatus(Ekos::CaptureState newState); // Update Mount module status void setMountStatus(ISD::Telescope::Status newState); + void setMountCoords(const QString &ra, const QString &dec, const QString &az, const QString &alt); + // Update Pier Side void setPierSide(ISD::Telescope::PierSide newSide); diff --git a/kstars/ekos/guide/guide.cpp b/kstars/ekos/guide/guide.cpp --- a/kstars/ekos/guide/guide.cpp +++ b/kstars/ekos/guide/guide.cpp @@ -1622,7 +1622,7 @@ void Guide::setPierSide(ISD::Telescope::PierSide newSide) { - Q_UNUSED(newSide); + guider->setPierSide(newSide); // If pier side changes in internal guider // and calibration was already done @@ -1685,6 +1685,11 @@ } } +void Guide::setMountCoords(const QString &ra, const QString &dec, const QString &az, const QString &alt) +{ + guider->setMountCoords(ra, dec, az, alt); +} + void Guide::setExposure(double value) { exposureIN->setValue(value); diff --git a/kstars/ekos/guide/guideinterface.h b/kstars/ekos/guide/guideinterface.h --- a/kstars/ekos/guide/guideinterface.h +++ b/kstars/ekos/guide/guideinterface.h @@ -10,7 +10,7 @@ #pragma once #include "ekos/ekos.h" - +#include "indi/inditelescope.h" #include #include @@ -58,6 +58,9 @@ virtual void setStarPosition(QVector3D& starCenter); + virtual void setMountCoords(const QString &ra, const QString &dec, const QString &az, const QString &alt); + virtual void setPierSide(ISD::Telescope::PierSide newSide); + enum CalibrationUpdateType { RA_IN, @@ -92,5 +95,9 @@ uint16_t subH { 0 }; uint16_t subBinX { 1 }; uint16_t subBinY { 1 }; + + // Recent mount position. + dms mountRA, mountDEC, mountAzimuth, mountAltitude; + ISD::Telescope::PierSide pierSide { ISD::Telescope::PIER_UNKNOWN }; }; } diff --git a/kstars/ekos/guide/guideinterface.cpp b/kstars/ekos/guide/guideinterface.cpp --- a/kstars/ekos/guide/guideinterface.cpp +++ b/kstars/ekos/guide/guideinterface.cpp @@ -70,4 +70,18 @@ { INDI_UNUSED(starCenter); } + +void GuideInterface::setMountCoords(const QString &ra, const QString &dec, const QString &az, const QString &alt) +{ + mountRA = dms::fromString(ra, false); + mountDEC = dms::fromString(dec, true); + mountAzimuth = dms::fromString(az, true); + mountAltitude = dms::fromString(alt, true); +} + +void GuideInterface::setPierSide(ISD::Telescope::PierSide newSide) +{ + pierSide = newSide; +} + } diff --git a/kstars/ekos/guide/internalguide/gmath.h b/kstars/ekos/guide/internalguide/gmath.h --- a/kstars/ekos/guide/internalguide/gmath.h +++ b/kstars/ekos/guide/internalguide/gmath.h @@ -23,6 +23,7 @@ #include #include +#include "guidelog.h" class FITSView; class FITSData; @@ -154,7 +155,7 @@ void setLostStar(bool is_lost); // Main processing function - void performProcessing(void); + void performProcessing(GuideLog *logger = nullptr); // Math bool calculateAndSetReticle1D(double start_x, double start_y, double end_x, double end_y, int RATotalPulse = -1); @@ -189,7 +190,7 @@ void calc_square_err(void); const char *get_direction_string(GuideDirection dir); - // Logging + // Old-stye Logging--deprecate. void createGuideLog(); /// Global channel ticker diff --git a/kstars/ekos/guide/internalguide/gmath.cpp b/kstars/ekos/guide/internalguide/gmath.cpp --- a/kstars/ekos/guide/internalguide/gmath.cpp +++ b/kstars/ekos/guide/internalguide/gmath.cpp @@ -158,6 +158,7 @@ *guider_focal = focal; } +// This logging will be removed in favor of guidelog.h. void cgmath::createGuideLog() { logFile.close(); @@ -1292,7 +1293,7 @@ } } -void cgmath::performProcessing(void) +void cgmath::performProcessing(GuideLog *logger) { Vector arc_star_pos, arc_reticle_pos; @@ -1306,6 +1307,13 @@ if (star_pos.x == -1 || std::isnan(star_pos.x)) { lost_star = true; + if (logger != nullptr && !preview_mode) + { + GuideLog::GuideData data; + data.code = GuideLog::GuideData::NO_STAR_FOUND; + data.type = GuideLog::GuideData::DROP; + logger->addGuideData(data); + } return; } else @@ -1360,6 +1368,26 @@ // finally process tickers do_ticks(); + if (logger != nullptr) + { + GuideLog::GuideData data; + data.type = GuideLog::GuideData::MOUNT; + data.dx = scr_star_pos.x - reticle_pos.x; + data.dy = scr_star_pos.y - reticle_pos.y; + data.raDistance = star_pos.x; + data.decDistance = star_pos.y; + // The guide distances are related to the raw distances above, but + // e.g. small differences can be ignored. We just copy. + data.raGuideDistance = star_pos.x; + data.decGuideDistance = star_pos.y; + data.raDuration = out_params.pulse_length[GUIDE_RA]; + data.raDirection = out_params.pulse_dir[GUIDE_RA]; + data.decDuration = out_params.pulse_length[GUIDE_DEC]; + data.decDirection = out_params.pulse_dir[GUIDE_DEC]; + data.code = GuideLog::GuideData::NO_ERROR; + // Add SNR and MASS from SEP stars. + logger->addGuideData(data); + } qCDebug(KSTARS_EKOS_GUIDE) << "################## FINISH PROCESSING ##################"; } diff --git a/kstars/ekos/guide/internalguide/guidelog.h b/kstars/ekos/guide/internalguide/guidelog.h new file mode 100644 --- /dev/null +++ b/kstars/ekos/guide/internalguide/guidelog.h @@ -0,0 +1,112 @@ +/* GuideLog class. + Copyright (C) 2020 Hy Murveit + + This application is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + */ + +#pragma once + +#include +#include + +#include "indi/indicommon.h" +#include "indi/inditelescope.h" + +// This class will help write guide log files, using the PHD2 guide log format. + +class GuideLog +{ +public: + class GuideInfo + { + public: + double pixelScale = 0; + int binning = 1; + double focalLength = 0; + // Recent mount position. + double ra = 0, dec = 0, azimuth = 0, altitude = 0; + ISD::Telescope::PierSide pierSide; + }; + + class GuideData + { + public: + enum GuideDataType { MOUNT, DROP }; + GuideDataType type; + double dx, dy; + double raDistance, decDistance; + double raGuideDistance, decGuideDistance; + int raDuration, decDuration; + GuideDirection raDirection, decDirection; + double mass; + double snr; + // From https://openphdguiding.org/PHD2_User_Guide.pdf and logs + enum ErrorCode { + NO_ERROR = 0, + STAR_SATURATED = 1, + LOW_SNR = 2, + STAR_LOST_LOW_MASS = 3, + EDGE_OF_FRAME = 4, + STAR_MASS_CHANGED = 5, + STAR_LOST_MASS_CHANGED = 6, + NO_STAR_FOUND = 7 + }; + ErrorCode code; + }; + + GuideLog(); + ~GuideLog(); + + // Won't log unless enable() is called. + void enable() { enabled = true; } + void disable() { enabled = false; } + + // These are called for each guiding session. + void startGuiding(const GuideInfo &info); + void addGuideData(const GuideData &data); + void endGuiding(); + + // These are called for each calibration session. + void startCalibration(const GuideInfo &info); + void addCalibrationData(GuideDirection direction, double x, double y, double xOrigin, double yOrigin); + void endCalibrationSection(GuideDirection direction, double degrees); + void endCalibration(double raSpeed = 0, double decSpeed = 0); + + // INFO messages + void ditherInfo(double dx, double dy, double x, double y); + void pauseInfo(); + void resumeInfo(); + void settleStartedInfo(); + void settleCompletedInfo(); + + // Deal with suspend, resume, dither, ... +private: + // Write the file header and footer. + void startLog(); + void endLog(); + void appendToLog(const QString &lines); + + // Log file info. + QFile logFile; + QString logFileName; + + // Message indeces and timers. + int guideIndex = 1; + int calibrationIndex = 1; + QElapsedTimer timer; + + // Used to write and end-of-guiding message on exit, if this was not called. + bool isGuiding = false; + + // Variable used to detect calibration change of direction. + GuideDirection lastCalibrationDirection = NO_DIR; + + // If false, no logging will occur. + bool enabled = false; + + // True means the filename was created and the log's header has been written. + bool initialized = false; +}; diff --git a/kstars/ekos/guide/internalguide/guidelog.cpp b/kstars/ekos/guide/internalguide/guidelog.cpp new file mode 100644 --- /dev/null +++ b/kstars/ekos/guide/internalguide/guidelog.cpp @@ -0,0 +1,299 @@ +/* GuideLog class. + Copyright (C) 2020 Hy Murveit + + This application is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + */ + +#include "guidelog.h" + +#include +#include + +#include +#include +#include + +#include "auxiliary/kspaths.h" +#include + +// This class writes a guide log that is compatible with the phdlogview program. +// See https://openphdguiding.org/phd2-log-viewer/ for details on that program. + +namespace { + +// These conversion aren't correct. I believe the KStars way of doing it, with RA_INC etc +// is better, however, it is consistent and will work with phdlogview. +QString directionString(GuideDirection direction) +{ + switch(direction) + { + case DEC_INC_DIR: return "N"; + case DEC_DEC_DIR: return "S"; + case RA_DEC_DIR: return "E"; + case RA_INC_DIR: return "W"; + case NO_DIR: return ""; + } + return ""; +} + +QString directionStringLong(GuideDirection direction) +{ + switch(direction) + { + case DEC_INC_DIR: return "North"; + case DEC_DEC_DIR: return "South"; + case RA_DEC_DIR: return "East"; + case RA_INC_DIR: return "West"; + case NO_DIR: return ""; + } + return ""; +} + +QString pierSideString(ISD::Telescope::PierSide side) +{ + switch(side) + { + case ISD::Telescope::PierSide::PIER_WEST: return QString("West"); + case ISD::Telescope::PierSide::PIER_EAST: return QString("East"); + case ISD::Telescope::PierSide::PIER_UNKNOWN: return QString("Unknown"); + } + return QString(""); +} + +double degreesToHours(double degrees) +{ + return 24.0 * degrees / 360.0; +} + +} // namespace + +GuideLog::GuideLog() +{ +} + +GuideLog::~GuideLog() +{ + endLog(); +} + +void GuideLog::appendToLog(const QString &lines) +{ + if (!enabled) + return; + QTextStream out(&logFile); + out << lines; + out.flush(); +} + +// Creates the filename and opens the file. +// Prints a line like the one below. +// KStars version 3.4.0. PHD2 log version 2.5. Log enabled at 2019-11-21 00:00:48 +void GuideLog::startLog() +{ + logFileName = KSPaths::writableLocation(QStandardPaths::GenericDataLocation) + + "guide_log-" + QDateTime::currentDateTime().toString("yyyy-MM-ddThh-mm-ss") + ".txt"; + logFile.setFileName(logFileName); + logFile.open(QIODevice::WriteOnly | QIODevice::Text); + + appendToLog(QString("KStars version %1. PHD2 log version 2.5. Log enabled at %2\n") + .arg(KSTARS_VERSION) + .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))); + + initialized = true; +} + +// Prints a line like the one below and closes the file. +// Log closed at 2019-11-21 08:46:38 +void GuideLog::endLog() +{ + if (!enabled || !initialized) + return; + + if (isGuiding && initialized) + endGuiding(); + + appendToLog(QString("Log closed at %1\n") + .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))); + logFile.close(); +} + +// Output at the start of Guiding. +// Note that in the PHD2 generated versions of this log, there is a lot of guiding information here. +// We just output two lines which phdlogview needs, for pixel scale and RA/DEC. +void GuideLog::startGuiding(const GuideInfo &info) +{ + if (!enabled) + return; + if (!initialized) + startLog(); + + // Currently phdlogview just reads the Pixel scale value on the 2nd line, and + // just reads the Dec value on the 3rd line. + // Note the log wants hrs for RA, the input to this method is in degrees. + appendToLog(QString("Guiding Begins at %1\n" + "Pixel scale = %2 arc-sec/px, Binning = %3, Focal length = %4 mm\n" + "RA = %5 hr, Dec = %6 deg, Hour angle = N/A hr, Pier side = %7, " + "Rotator pos = N/A, Alt = %8 deg, Az = %9 deg\n" + "Frame,Time,mount,dx,dy,RARawDistance,DECRawDistance,RAGuideDistance,DECGuideDistance," + "RADuration,RADirection,DECDuration,DECDirection,XStep,YStep,StarMass,SNR,ErrorCode\n") + .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) + .arg(QString::number(info.pixelScale, 'f', 2)) + .arg(info.binning) + .arg(info.focalLength) + .arg(QString::number(degreesToHours(info.ra), 'f', 2)) + .arg(QString::number(info.dec, 'f', 1)) + .arg(pierSideString(info.pierSide)) + .arg(QString::number(info.altitude, 'f', 1)) + .arg(QString::number(info.azimuth, 'f', 1))); + + guideIndex = 1; + isGuiding = true; + timer.start(); +} + +// Prints a line that looks something like this: +// 55,467.914,"Mount",-1.347,-2.160,2.319,-1.451,1.404,-0.987,303,W,218,N,,,2173,26.91,0 +// See page 56-57 in https://openphdguiding.org/PHD2_User_Guide.pdf for definitions of the fields. +void GuideLog::addGuideData(const GuideData &data) +{ + QString mountString = data.type == GuideData::MOUNT ? "\"Mount\"" : "\"DROP\""; + QString xStepString = ""; + QString yStepString = ""; + appendToLog(QString("%1,%2,%3,%4,%5,%6,%7,%8,%9,%10,%11,%12,%13,%14,%15,%16,%17,%18\n") + .arg(guideIndex) + .arg(QString::number(timer.elapsed() / 1000.0, 'f', 3)) + .arg(mountString) + .arg(QString::number(data.dx, 'f', 3)) + .arg(QString::number(data.dy, 'f', 3)) + .arg(QString::number(data.raDistance, 'f', 3)) + .arg(QString::number(data.decDistance, 'f', 3)) + .arg(QString::number(data.raGuideDistance, 'f', 3)) + .arg(QString::number(data.decGuideDistance, 'f', 3)) + .arg(data.raDuration) + .arg(directionString(data.raDirection)) + .arg(data.decDuration) + .arg(directionString(data.decDirection)) + .arg(xStepString) + .arg(yStepString) + .arg(QString::number(data.mass, 'f', 0)) + .arg(QString::number(data.snr, 'f', 2)) + .arg(static_cast(data.code))); + ++guideIndex; +} + +// Prints a line that looks like: +// Guiding Ends at 2019-11-21 01:57:45 +void GuideLog::endGuiding() +{ + appendToLog(QString("Guiding Ends at %1\n") + .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))); + isGuiding = false; +} + +// Note that in the PHD2 generated versions of this log, there is a lot of calibration information here. +// We just output two lines which phdlogview needs, for pixel scale and RA/DEC. +void GuideLog::startCalibration(const GuideInfo &info) +{ + if (!enabled) + return; + if (!initialized) + startLog(); + // Currently phdlogview just reads the Pixel scale value on the 2nd line, and + // just reads the Dec value on the 3rd line. + appendToLog(QString("Calibration Begins at %1\n" + "Pixel scale = %2 arc-sec/px, Binning = %3, Focal length = %4 mm\n" + "RA = %5 hr, Dec = %6 deg, Hour angle = N/A hr, Pier side = %7, " + "Rotator pos = N/A, Alt = %8 deg, Az = %9 deg\n" + "Direction,Step,dx,dy,x,y,Dist\n") + .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) + .arg(QString::number(info.pixelScale, 'f', 2)) + .arg(info.binning) + .arg(info.focalLength) + .arg(QString::number(degreesToHours(info.ra), 'f', 2)) + .arg(QString::number(info.dec, 'f', 1)) + .arg(pierSideString(info.pierSide)) + .arg(QString::number(info.altitude, 'f', 1)) + .arg(QString::number(info.azimuth, 'f', 1))); + + calibrationIndex = 1; + timer.start(); + lastCalibrationDirection = NO_DIR; +} + +// Prints a line that looks like: +// West,2,-15.207,-1.037,54.800,58.947,15.242 +void GuideLog::addCalibrationData(GuideDirection direction, double x, double y, double xOrigin, double yOrigin) +{ + if (direction != lastCalibrationDirection) + calibrationIndex = 1; + lastCalibrationDirection = direction; + + appendToLog(QString("%1,%2,%3,%4,%5,%6,%7\n") + .arg(directionStringLong(direction)) + .arg(calibrationIndex) + .arg(QString::number(x - xOrigin, 'f', 3)) + .arg(QString::number(y - yOrigin, 'f', 3)) + .arg(QString::number(x, 'f', 3)) + .arg(QString::number(y, 'f', 3)) + .arg(QString::number(hypot(x - xOrigin, y - yOrigin), 'f', 3))); + + // This is a little different than PHD2--they seem to count down in the reverse directions. + calibrationIndex++; +} + +// Prints a line that looks like: +// West calibration complete. Angle = 106.8 deg +// Currently phdlogview ignores this line. +void GuideLog::endCalibrationSection(GuideDirection direction, double degrees) +{ + appendToLog(QString("%1 calibration complete. Angle = %2 deg\n") + .arg(directionStringLong(direction)) + .arg(QString::number(degrees, 'f', 1))); +} + +// Prints two lines that look like: +// Calibration guide speeds: RA = 191.5 a-s/s, Dec = 408.0 a-s/s +// Calibration complete +// The failed version is not in the PHD2 log, will be ignored by the viewer. +void GuideLog::endCalibration(double raSpeed, double decSpeed) +{ + if (raSpeed == 0 && decSpeed == 0) + appendToLog(QString("Calibration complete (Failed)\n")); + else + appendToLog(QString("Calibration guide speeds: RA = %1 a-s/s, Dec = %2 a-s/s\n" + "Calibration complete\n") + .arg(QString::number(raSpeed, 'f', 1)) + .arg(QString::number(decSpeed, 'f', 1))); +} + +void GuideLog::ditherInfo(double dx, double dy, double x, double y) +{ + appendToLog(QString("INFO: DITHER by %1, %2, new lock pos = %3, %4\n") + .arg(QString::number(dx, 'f', 3)) + .arg(QString::number(dy, 'f', 3)) + .arg(QString::number(x, 'f', 3)) + .arg(QString::number(y, 'f', 3))); +} + +void GuideLog::pauseInfo() +{ + appendToLog("INFO: Server received PAUSE\n"); +} + +void GuideLog::resumeInfo() +{ + appendToLog("INFO: Server received RESUME\n"); +} + +void GuideLog::settleStartedInfo() +{ + appendToLog("INFO: SETTLING STATE CHANGE, Settling started\n"); +} + +void GuideLog::settleCompletedInfo() +{ + appendToLog("INFO: SETTLING STATE CHANGE, Settling complete\n"); +} diff --git a/kstars/ekos/guide/internalguide/internalguider.h b/kstars/ekos/guide/internalguide/internalguider.h --- a/kstars/ekos/guide/internalguide/internalguider.h +++ b/kstars/ekos/guide/internalguide/internalguider.h @@ -14,6 +14,7 @@ #include "matr.h" #include "indi/indicommon.h" #include "../guideinterface.h" +#include "guidelog.h" #include #include @@ -168,6 +169,9 @@ void reset(); + // Logging + void fillGuideInfo(GuideLog::GuideInfo *info); + std::unique_ptr pmath; QPointer guideFrame; bool m_isStarted { false }; @@ -238,5 +242,6 @@ static const uint8_t MAX_DITHER_TRAVEL = 15; QPair accumulator; + GuideLog guideLog; }; } diff --git a/kstars/ekos/guide/internalguide/internalguider.cpp b/kstars/ekos/guide/internalguide/internalguider.cpp --- a/kstars/ekos/guide/internalguide/internalguider.cpp +++ b/kstars/ekos/guide/internalguide/internalguider.cpp @@ -80,6 +80,15 @@ m_isFirstFrame = true; + if (state == GUIDE_IDLE) + { + if (Options::saveGuideLog()) + guideLog.enable(); + GuideLog::GuideInfo info; + fillGuideInfo(&info); + guideLog.startGuiding(info); + } + state = GUIDE_GUIDING; emit newStatus(state); @@ -93,6 +102,7 @@ calibrationStage = CAL_IDLE; logFile.close(); + guideLog.endGuiding(); if (state == GUIDE_CALIBRATING || state == GUIDE_GUIDING || state == GUIDE_DITHERING || state == GUIDE_MANUAL_DITHERING) { @@ -121,6 +131,7 @@ bool InternalGuider::suspend() { + guideLog.pauseInfo(); state = GUIDE_SUSPENDED; emit newStatus(state); @@ -131,6 +142,7 @@ bool InternalGuider::resume() { + guideLog.resumeInfo(); state = GUIDE_GUIDING; emit newStatus(state); @@ -175,6 +187,7 @@ m_DitherTargetPosition = m_ProgressiveDither.dequeue(); pmath->setReticleParameters(m_DitherTargetPosition.x, m_DitherTargetPosition.y, m_DitherTargetPosition.z); + guideLog.ditherInfo(x, y, m_DitherTargetPosition.x, m_DitherTargetPosition.y); state = GUIDE_MANUAL_DITHERING; emit newStatus(state); @@ -217,6 +230,7 @@ qCDebug(KSTARS_EKOS_GUIDE) << "Dithering process started.. Reticle Target Pos X " << m_DitherTargetPosition.x << " Y " << m_DitherTargetPosition.y; + guideLog.ditherInfo(diff_x, diff_y, m_DitherTargetPosition.x, m_DitherTargetPosition.y); pmath->setReticleParameters(m_DitherTargetPosition.x, m_DitherTargetPosition.y, ret_angle); @@ -242,6 +256,7 @@ if (Options::ditherSettle() > 0) { state = GUIDE_DITHERING_SETTLE; + guideLog.settleStartedInfo(); emit newStatus(state); } @@ -265,6 +280,7 @@ if (Options::ditherSettle() > 0) { state = GUIDE_DITHERING_SETTLE; + guideLog.settleStartedInfo(); emit newStatus(state); } @@ -314,6 +330,7 @@ if (Options::ditherSettle() > 0) { state = GUIDE_DITHERING_SETTLE; + guideLog.settleStartedInfo(); emit newStatus(state); } @@ -333,6 +350,7 @@ if (Options::ditherSettle() > 0) { state = GUIDE_DITHERING_SETTLE; + guideLog.settleStartedInfo(); emit newStatus(state); } @@ -348,6 +366,7 @@ void InternalGuider::setDitherSettled() { + guideLog.settleCompletedInfo(); emit newStatus(Ekos::GUIDE_DITHERING_SUCCESS); // Back to guiding @@ -402,6 +421,11 @@ pmath->setLostStar(false); calibrationStage = CAL_START; + if (Options::saveGuideLog()) + guideLog.enable(); + GuideLog::GuideInfo info; + fillGuideInfo(&info); + guideLog.startCalibration(info); // automatic // If two axies (RA/DEC) are required @@ -504,6 +528,10 @@ m_CalibrationParams.ra_iterations++; calibrationStage = CAL_RA_INC; + guideLog.addCalibrationData( + RA_INC_DIR, + m_CalibrationCoords.start_x1, m_CalibrationCoords.start_y1, + m_CalibrationCoords.start_x1, m_CalibrationCoords.start_y1); break; @@ -520,6 +548,9 @@ qCDebug(KSTARS_EKOS_GUIDE) << "Iteration " << m_CalibrationParams.ra_iterations << " Direction: RA_INC_DIR" << " Duration: " << m_CalibrationParams.last_pulse << " ms."; + guideLog.addCalibrationData(RA_INC_DIR, cur_x, cur_y, + m_CalibrationCoords.start_x1, m_CalibrationCoords.start_y1); + // Must pass at least 1.5 pixels to move on to the next stage if (m_CalibrationParams.ra_iterations >= m_CalibrationParams.auto_drift_time && (fabs(cur_x - m_CalibrationCoords.start_x1) > 1.5 || fabs(cur_y - m_CalibrationCoords.start_y1) > 1.5)) @@ -547,6 +578,7 @@ m_CalibrationParams.ra_iterations++; emit newLog(i18n("RA drifting reverse...")); + guideLog.endCalibrationSection(RA_INC_DIR, m_CalibrationParams.phi); } else if (m_CalibrationParams.ra_iterations > m_CalibrationParams.turn_back_time) { @@ -558,6 +590,7 @@ emit calibrationUpdate(GuideInterface::CALIBRATION_MESSAGE_ONLY, i18n("Calibration Failed: Drift too short.")); KSNotification::event(QLatin1String("CalibrationFailed"), i18n("Guiding calibration failed with errors"), KSNotification::EVENT_ALERT); + guideLog.endCalibration(); reset(); } @@ -606,6 +639,9 @@ if (m_CalibrationCoords.ra_distance == 0.0) m_CalibrationCoords.ra_distance = star_pos.x; + guideLog.addCalibrationData(RA_DEC_DIR, cur_x, cur_y, + m_CalibrationCoords.start_x1, m_CalibrationCoords.start_y1); + // start point reached... so exit if (star_pos.x < 1.5) { @@ -722,6 +758,10 @@ qCDebug(KSTARS_EKOS_GUIDE) << "Iteration " << m_CalibrationParams.dec_iterations << " Direction: DEC_INC_DIR" << " Duration: " << m_CalibrationParams.last_pulse << " ms."; + // Don't yet know how to tell NORTH vs SOUTH + guideLog.addCalibrationData(DEC_INC_DIR, cur_x, cur_y, + m_CalibrationCoords.start_x2, m_CalibrationCoords.start_y2); + if (m_CalibrationParams.dec_iterations >= m_CalibrationParams.auto_drift_time && (fabs(cur_x - m_CalibrationCoords.start_x2) > 1.5 || fabs(cur_y - m_CalibrationCoords.start_y2) > 1.5)) { @@ -748,6 +788,7 @@ emit newPulse(DEC_DEC_DIR, m_CalibrationParams.last_pulse); emit newLog(i18n("DEC drifting reverse...")); m_CalibrationParams.dec_iterations++; + guideLog.endCalibrationSection(DEC_INC_DIR, m_CalibrationParams.phi); } else if (m_CalibrationParams.dec_iterations > m_CalibrationParams.turn_back_time) { @@ -763,6 +804,7 @@ KSNotification::event(QLatin1String("CalibrationFailed"), i18n("Guiding calibration failed with errors"), KSNotification::EVENT_ALERT); + guideLog.endCalibration(); reset(); } else @@ -811,6 +853,9 @@ if (m_CalibrationCoords.de_distance == 0.0) m_CalibrationCoords.de_distance = star_pos.x; + guideLog.addCalibrationData(DEC_DEC_DIR, cur_x, cur_y, + m_CalibrationCoords.start_x2, m_CalibrationCoords.start_y2); + // start point reached... so exit if (star_pos.x < 1.5) { @@ -883,6 +928,8 @@ //if (ui.autoStarCheck->isChecked()) //guideModule->selectAutoStar(); + + guideLog.endCalibration(pmath->getDitherRate(0), pmath->getDitherRate(1)); } else { @@ -895,6 +942,7 @@ calibrationStage = CAL_ERROR; KSNotification::event(QLatin1String("CalibrationFailed"), i18n("Guiding calibration failed with errors"), KSNotification::EVENT_ALERT); + guideLog.endCalibration(); } reset(); @@ -1006,7 +1054,7 @@ } // calc math. it tracks square - pmath->performProcessing(); + pmath->performProcessing(&guideLog); if (pmath->isStarLost()) m_starLostCounter++; @@ -1344,6 +1392,7 @@ if (Options::ditherSettle() > 0) { state = GUIDE_DITHERING_SETTLE; + guideLog.settleStartedInfo(); emit newStatus(state); } @@ -1367,4 +1416,19 @@ return rc; } +void InternalGuider::fillGuideInfo(GuideLog::GuideInfo *info) +{ + // NOTE: just using the X values, phd2logview assumes x & y the same. + // pixel scale in arc-sec / pixel. The 2nd and 3rd values seem redundent, but are + // in the phd2 logs. + info->pixelScale = this->ccdPixelSizeX * this->subBinX * this->mountFocalLength / 206.264; + info->binning = this->subBinX; + info->focalLength = this->mountFocalLength; + info->ra = this->mountRA.Degrees(); + info->dec = this->mountDEC.Degrees(); + info->azimuth = this->mountAzimuth.Degrees(); + info->altitude = this->mountAltitude.Degrees(); + info->pierSide = this->pierSide; +} + } diff --git a/kstars/ekos/guide/opsguide.ui b/kstars/ekos/guide/opsguide.ui --- a/kstars/ekos/guide/opsguide.ui +++ b/kstars/ekos/guide/opsguide.ui @@ -97,6 +97,19 @@ + + + + <html><head/><body><p>If checked and the internal guider is run, a log file is saved in the default logging directory. This is not a debug log, it is meant for user's to improve logging and can be viewed with phd2logview.</p></body></html> + + + true + + + Save Internal Guider User Log + + + diff --git a/kstars/ekos/manager.cpp b/kstars/ekos/manager.cpp --- a/kstars/ekos/manager.cpp +++ b/kstars/ekos/manager.cpp @@ -3317,6 +3317,9 @@ // Parking connect(mountProcess.get(), &Ekos::Mount::newStatus, guideProcess.get(), &Ekos::Guide::setMountStatus, Qt::UniqueConnection); + connect(mountProcess.get(), &Ekos::Mount::newCoords, guideProcess.get(), &Ekos::Guide::setMountCoords, + Qt::UniqueConnection); + } // Focus <---> Guide connections diff --git a/kstars/kstars.kcfg b/kstars/kstars.kcfg --- a/kstars/kstars.kcfg +++ b/kstars/kstars.kcfg @@ -2173,6 +2173,10 @@ false + + + true + false