[kstars] kstars/ekos/guide/externalguide: This patch should add several improvements to the PHD2 interface in KStars. Here is a list.

Jasem Mutlaq null at kde.org
Tue Dec 12 08:37:25 UTC 2017


Git commit 755e8df3bd343fba8de85f64ac481d27a3f404d1 by Jasem Mutlaq, on behalf of Robert Lancaster.
Committed on 12/12/2017 at 08:36.
Pushed by mutlaqja into branch 'master'.

This patch should add several improvements to the PHD2 interface in KStars.  Here is a list.
1.  Makes sure the temp directory exists so that the guide star images will have a place to go.
2.  Adds a new enum for the PHD results which will make adding more methods to get information back from PHD2 easier because you will know what result you are waiting for and what variable to put the result into.
3.  Adds several new methods to get crucial information from PHD2 including get exposure, get pixel scale, and request star image.  These should be easier to use than the previous multiline method of requesting info.
4.  Adds RMS/sigma reporting for the RA and DEC errors.  Uses the last 50 errors for the report.  Prevents nan and inf numbers from being added into the error report.
5.  Sets the exposure time box to PHD2’s exposure time so the user knows what it is.
6.  Gets the pixel scale directly from PHD2 and uses that for the error calculations.
7.  Blocks errors that would print as a result of guide star images that accidentally get separated in transit.

I tested this both running locally on my Mac and over the network to my raspberry Pi.

CCMAIL:kstars-devel at kde.org

M  +101  -13   kstars/ekos/guide/externalguide/phd2.cpp
M  +23   -2    kstars/ekos/guide/externalguide/phd2.h

https://commits.kde.org/kstars/755e8df3bd343fba8de85f64ac481d27a3f404d1

diff --git a/kstars/ekos/guide/externalguide/phd2.cpp b/kstars/ekos/guide/externalguide/phd2.cpp
index 71fbf436c..54390631d 100644
--- a/kstars/ekos/guide/externalguide/phd2.cpp
+++ b/kstars/ekos/guide/externalguide/phd2.cpp
@@ -58,6 +58,9 @@ PHD2::PHD2()
     events["GuidingDithered"]         = GuidingDithered;
     events["LockPositionLost"]        = LockPositionLost;
     events["Alert"]                   = Alert;
+
+    QDir writableDir;
+    writableDir.mkdir(KSPaths::writableLocation(QStandardPaths::TempLocation));
 }
 
 PHD2::~PHD2()
@@ -130,8 +133,17 @@ void PHD2::readPHD2()
 
         if (qjsonError.error != QJsonParseError::NoError)
         {
-            emit newLog(rawString);
-            emit newLog(qjsonError.errorString());
+            //So we don't spam the error log with image frames that accidentally get broken up.
+            if(rawString.contains("frame"))     //This prevents it from printing the first line of the error.
+                blockLine2=true;                //This will set it to watch for the second line to cause an error.
+            else if(blockLine2)                 //This will prevent it from printing the second line of the error.
+                blockLine2=false;               //After avoiding printing the error message, this will set it to look for errors again.
+            else
+            {
+                //This will still print other parsing errors that don't involve image frames.
+                emit newLog(rawString);
+                emit newLog(qjsonError.errorString());
+            }
             continue;
         }
 
@@ -158,30 +170,56 @@ void PHD2::processJSON(const QJsonObject &jsonObj, QString rawString)
     }
     else if (jsonObj.contains("result"))
     {
+        //This is a special result/message type, the Star Image.  We want to handle it separately from the others so it doesn't print massive amounts of data to the log.
         QJsonObject jsonResult = jsonObj["result"].toObject();
         if (jsonResult.contains("frame"))
         {
                 messageType = PHD2_STAR_IMAGE;
                 processStarImage(jsonResult);
+                return;
         }
         else
-        {
             messageType = PHD2_RESULT;
-        }
     }
 
-    if(messageType != PHD2_STAR_IMAGE)
-        qCDebug(KSTARS_EKOS_GUIDE) << rawString;
+    qCDebug(KSTARS_EKOS_GUIDE) << rawString;
+
+    if(messageType == PHD2_RESULT){
+        switch (desiredResult)
+        {
+            case NO_RESULT:
+            case CONNECTION_RESULT:
+                desiredResult=NO_RESULT;
+                //These will be handled below in the next switch statement.
+                break;
+
+            case PIXEL_SCALE:
+                pixelScale=jsonObj["result"].toDouble();
+                desiredResult=NO_RESULT;
+                return;
+
+            case EXPOSURE_TIME:
+                int exposurems=jsonObj["result"].toInt();
+                KStars::Instance()->ekosManager()->guideModule()->setExposure(exposurems/1000.0);
+                desiredResult=NO_RESULT;
+                return;
+        }
+    }
 
     switch (connection)
     {
         case CONNECTING:
-            if (event == Version)
+            if (event == Version){
                 connection = CONNECTED;
+                if(pixelScale==0)
+                    requestPixelScale();
+            }
             return;
 
         case CONNECTED:
             // If initial state is STOPPED, let us connect equipment
+            if(pixelScale==0)
+                requestPixelScale();
             if (state == STOPPED || state == PAUSED)
             {
                 setEquipmentConnected(true);
@@ -202,6 +240,7 @@ void PHD2::processJSON(const QJsonObject &jsonObj, QString rawString)
             {
                 connection = EQUIPMENT_CONNECTED;
                 emit newStatus(Ekos::GUIDE_CONNECTED);
+                requestPixelScale();
             }
             else if (messageType == PHD2_ERROR)
             {
@@ -273,6 +312,7 @@ void PHD2::processPHD2Event(const QJsonObject &jsonEvent)
             }
             emit newLog(i18n("PHD2: Guiding Started."));
             emit newStatus(Ekos::GUIDE_GUIDING);
+            requestExposureTime();
             break;
 
         case Paused:
@@ -373,14 +413,40 @@ void PHD2::processPHD2Event(const QJsonObject &jsonEvent)
             diff_ra_pixels = jsonEvent["RADistanceRaw"].toDouble();
             diff_de_pixels = jsonEvent["DECDistanceRaw"].toDouble();
 
-            diff_ra_arcsecs = 206.26480624709 * diff_ra_pixels * ccdPixelSizeX / mountFocalLength;
-            diff_de_arcsecs = 206.26480624709 * diff_de_pixels * ccdPixelSizeY / mountFocalLength;
+            //If the pixelScale is properly set from PHD2, the second block of code is not needed, but if not, we will attempt to calculate the ra and dec error without it.
+            if(pixelScale!=0)
+            {
+                diff_ra_arcsecs = diff_ra_pixels * pixelScale;
+                diff_de_arcsecs = diff_de_pixels * pixelScale;
+            }
+            else
+            {
+                diff_ra_arcsecs = 206.26480624709 * diff_ra_pixels * ccdPixelSizeX / mountFocalLength;
+                diff_de_arcsecs = 206.26480624709 * diff_de_pixels * ccdPixelSizeY / mountFocalLength;
+            }
+
+            if (std::isfinite(diff_ra_arcsecs) && std::isfinite(diff_de_arcsecs))
+            {
+                errorLog.append(QPointF(diff_ra_arcsecs, diff_de_arcsecs));
+                if(errorLog.size()>50)
+                    errorLog.remove(0);
+
+                emit newAxisDelta(diff_ra_arcsecs, diff_de_arcsecs);
+
+                double total_sqr_RA_error;
+                double total_sqr_DE_error;
+                for(int i=0;i<errorLog.size();i++)
+                {
+                    QPointF point=errorLog.at(i);
+                    total_sqr_RA_error+=point.x()*point.x();
+                    total_sqr_DE_error+=point.y()*point.y();
+                }
+
+                emit newAxisSigma(sqrt(total_sqr_RA_error/errorLog.size()), sqrt(total_sqr_DE_error/errorLog.size()));
 
-            emit newAxisDelta(diff_ra_arcsecs, diff_de_arcsecs);
+            }
 
-            QJsonArray args2;
-            args2<<32; //This is the size of the image that is being requested  32 x 32 pixels.
-            sendJSONRPCRequest("get_star_image", args2); //This requests a star image for the guide view.
+            requestStarImage(32); //This requests a star image for the guide view.  32 x 32 pixels
         }
         break;
 
@@ -506,6 +572,24 @@ void PHD2::processPHD2Error(const QJsonObject &jsonError)
      }*/
 }
 
+void PHD2::requestPixelScale(){
+    QJsonArray args;
+    desiredResult=PIXEL_SCALE;
+    sendJSONRPCRequest("get_pixel_scale", args);
+}
+
+void PHD2::requestExposureTime(){
+    QJsonArray args;
+    desiredResult=EXPOSURE_TIME;
+    sendJSONRPCRequest("get_exposure", args);
+}
+
+void PHD2::requestStarImage(int size){
+    QJsonArray args2;
+    args2<<size; //This is both the width and height.
+    sendJSONRPCRequest("get_star_image", args2);
+}
+
 void PHD2::sendJSONRPCRequest(const QString &method, const QJsonArray args)
 {
     QJsonObject jsonRPC;
@@ -552,6 +636,8 @@ void PHD2::setEquipmentConnected(bool enable)
     args << enable;
 
     sendJSONRPCRequest("set_connected", args);
+    desiredResult=CONNECTION_RESULT;
+
 }
 
 bool PHD2::calibrate()
@@ -588,6 +674,8 @@ bool PHD2::guide()
     // Recalibrate param
     args << false;
 
+    errorLog.clear();
+
     sendJSONRPCRequest("guide", args);
 
     return true;
diff --git a/kstars/ekos/guide/externalguide/phd2.h b/kstars/ekos/guide/externalguide/phd2.h
index 9037b4cf8..8604196f9 100644
--- a/kstars/ekos/guide/externalguide/phd2.h
+++ b/kstars/ekos/guide/externalguide/phd2.h
@@ -79,8 +79,19 @@ class PHD2 : public GuideInterface
         EQUIPMENT_CONNECTING,
         EQUIPMENT_CONNECTED
     } PHD2Connection;
-    typedef enum { PHD2_UNKNOWN, PHD2_RESULT, PHD2_EVENT, PHD2_ERROR,
-                   PHD2_STAR_IMAGE } PHD2MessageType;
+    typedef enum {
+        PHD2_UNKNOWN,
+        PHD2_RESULT,
+        PHD2_EVENT,
+        PHD2_ERROR,
+        PHD2_STAR_IMAGE,
+    } PHD2MessageType;
+    typedef enum {
+        NO_RESULT,
+        PIXEL_SCALE,
+        EXPOSURE_TIME,
+        CONNECTION_RESULT
+    } PHD2ResultType;
 
     PHD2();
     ~PHD2();
@@ -97,6 +108,10 @@ class PHD2 : public GuideInterface
     bool dither(double pixels) override;
     bool clearCalibration() override;
 
+    void requestPixelScale();
+    void requestStarImage(int size);
+    void requestExposureTime();
+
     void setGuideView(FITSView *guideView);
 
   private slots:
@@ -110,8 +125,11 @@ class PHD2 : public GuideInterface
 
     QPointer<FITSView> guideFrame;
 
+    QVector<QPointF> errorLog;
+
     void sendJSONRPCRequest(const QString &method, const QJsonArray args = QJsonArray());
     void processJSON(const QJsonObject &jsonObj, QString rawString);
+    bool blockLine2=false;
 
     void processPHD2Event(const QJsonObject &jsonEvent);
     void processStarImage(const QJsonObject &jsonStarFrame);
@@ -126,6 +144,9 @@ class PHD2 : public GuideInterface
     PHD2State state { STOPPED };
     PHD2Connection connection { DISCONNECTED };
     PHD2Event event { Alert };
+    PHD2ResultType desiredResult { NO_RESULT };
     uint8_t setConnectedRetries { 0 };
+
+    double pixelScale=0;
 };
 }


More information about the Kstars-devel mailing list