[kstars] kstars/ekos/align: This patch will improve the functionality of the align points wizard.

Jasem Mutlaq null at kde.org
Sat Mar 11 11:14:39 UTC 2017


Git commit 6a0ef363cc1e6532eb6edf154a3d16920da1ad52 by Jasem Mutlaq, on behalf of Robert Lancaster.
Committed on 11/03/2017 at 11:11.
Pushed by mutlaqja into branch 'master'.

This patch will improve the functionality of the align points wizard.
I found some spherical trig in another part of kstars that I could modify slightly to calculate the points I needed for the align points wizard to truly generate equally distributed points along a particular dec line in the sky from the minimum altitude on either side of the sky.
In the process of the revision, I added a spin box for the minimum altitude so it is not just hard coded to 30 degrees anymore, I added another spin box so the user could specify the declination used for the align points.
This will allow the user to very quickly create a grid of align points to build a highly accurate pointing model.
I added an option to let the user choose whether to use bright alignment stars, any objects kstars finds near the points, or fixed points not connected to any object.
I also fixed the problem reported where the CSV file export fails because there is no name for a point.  I added the word “None" to fix it.

CCMAIL:kstars-devel at kde.org

M  +153  -63   kstars/ekos/align/align.cpp
M  +2    -1    kstars/ekos/align/align.h
M  +2    -2    kstars/ekos/align/align.ui
M  +179  -44   kstars/ekos/align/mountmodel.ui

https://commits.kde.org/kstars/6a0ef363cc1e6532eb6edf154a3d16920da1ad52

diff --git a/kstars/ekos/align/align.cpp b/kstars/ekos/align/align.cpp
index 57df6e889..be853f650 100644
--- a/kstars/ekos/align/align.cpp
+++ b/kstars/ekos/align/align.cpp
@@ -330,7 +330,7 @@ Align::Align()
     mountModelDialog.setWindowFlags(Qt::Tool| Qt::WindowStaysOnTopHint);
     mountModel.alignTable->setColumnWidth(0,70);
     mountModel.alignTable->setColumnWidth(1,75);
-    mountModel.alignTable->setColumnWidth(2,80);
+    mountModel.alignTable->setColumnWidth(2,100);
     mountModel.alignTable->setColumnWidth(3,30);
 
     mountModel.wizardAlignB->setIcon(QIcon::fromTheme("tools-wizard", QIcon(":/icons/breeze/default/tools-wizard.svg") ));
@@ -561,73 +561,152 @@ void Align::slotWizardAlignmentPoints(){
     int points=mountModel.alignPtNum->value();
     if(points<2)
         return;
-    double angle = 120 / (points-1);  //180 degrees of sky - 30 degrees at each horizon.
 
+    double decAngle=mountModel.alignDec->value();
+    int minAlt=mountModel.minAltBox->value();
+
+    KStarsData *data = KStarsData::Instance();
+    GeoLocation *geo=data->geo();
+
+    double lat=geo->lat()->Degrees();
+
+    //Dec that never rises.
+    if(lat>0){
+        if(decAngle < lat - 90 + minAlt)  //Min altitude possible at minAlt deg above horizon
+            return;
+
+    } else{
+        if(decAngle > lat + 90 - minAlt)  //Max altitude possible at minAlt deg above horizon
+            return;
+    }
+
+    double angle = -1;
+
+    SkyPoint spEast;
     SkyPoint spWest;
-    spWest.setAlt(30);
-    spWest.setAz(270);
-    spWest.HorizontalToEquatorial(KStars::Instance()->data()->lst(), KStars::Instance()->data()->geo()->lat());
+
+    //Circumpolar dec
+    if(fabs(decAngle)  >  (90 - fabs(lat) + minAlt)){
+        angle = 360 / (points-1);
+        spWest=SkyPoint(dms(0),dms(decAngle));
+    }else{
+        dms AZEast,AZWest;
+        calculateAZPointsForDEC(dms(decAngle), dms(minAlt), AZEast,AZWest);
+
+        spEast.setAlt(minAlt);
+        spEast.setAz(AZEast.Degrees());
+        spEast.HorizontalToEquatorial(KStars::Instance()->data()->lst(), KStars::Instance()->data()->geo()->lat());
+
+        spWest.setAlt(minAlt);
+        spWest.setAz(AZWest.Degrees());
+        spWest.HorizontalToEquatorial(KStars::Instance()->data()->lst(), KStars::Instance()->data()->geo()->lat());
+
+        dms angleSep;
+        if(spEast.ra().Degrees()>spWest.ra().Degrees())
+            angleSep=spEast.ra()-spWest.ra();
+        else
+            angleSep=spEast.ra()+dms(360)-spWest.ra();
+        angle=angleSep.Degrees()/(points-1);
+        //qDebug()<<"AZ Intersections: "<<QString::number(AZWest.Degrees())<<","<<QString::number(AZEast.Degrees());
+        //qDebug()<<"RA Values: "<<spWest.ra().toHMSString()<<", "<<spEast.ra().toHMSString();
+        //qDebug()<<"RA Degrees: "<<QString::number(spWest.ra().Degrees())<<","<<QString::number(spEast.ra().Degrees());
+        //qDebug()<<"AngleSep: "<<QString::number(angleSep.Degrees())<<","<<QString::number(angle);
+    }
+
+    if(angle==-1)
+        return;
 
     for(int i=0;i<points;i++){
         double ra=spWest.ra().Degrees()+i*angle;
-        double dec=spWest.dec().Degrees();
+        double dec=decAngle;
 
-        const SkyObject *o = getClosestAlignStar(ra,dec,angle);
+        const SkyObject *o = getWizardAlignObject(ra,dec,angle);
 
+        QString ra_report, dec_report, name;
         if(o){
-            int currentRow = mountModel.alignTable->rowCount();
-            mountModel.alignTable->insertRow(currentRow);
-
-            QString ra_report, dec_report;
             getFormattedCoords(o->ra().Hours(),o->dec().Degrees(),ra_report, dec_report);
+            name=o->longname();
+        } else{
+            getFormattedCoords(dms(ra).Hours(),dec,ra_report, dec_report);
+            name="None";
+        }
+        int currentRow = mountModel.alignTable->rowCount();
+        mountModel.alignTable->insertRow(currentRow);
+
+        QTableWidgetItem *RAReport = new QTableWidgetItem();
+        RAReport->setText(ra_report);
+        RAReport->setTextAlignment(Qt::AlignHCenter);
+        mountModel.alignTable->setItem(currentRow, 0, RAReport);
 
-            QTableWidgetItem *RAReport = new QTableWidgetItem();
-            RAReport->setText(ra_report);
-            RAReport->setTextAlignment(Qt::AlignHCenter);
-            mountModel.alignTable->setItem(currentRow, 0, RAReport);
+        QTableWidgetItem *DECReport = new QTableWidgetItem();
+        DECReport->setText(dec_report);
+        DECReport->setTextAlignment(Qt::AlignHCenter);
+        mountModel.alignTable->setItem(currentRow, 1, DECReport);
 
-            QTableWidgetItem *DECReport = new QTableWidgetItem();
-            DECReport->setText(dec_report);
-            DECReport->setTextAlignment(Qt::AlignHCenter);
-            mountModel.alignTable->setItem(currentRow, 1, DECReport);
+        QTableWidgetItem *ObjNameReport = new QTableWidgetItem();
+        ObjNameReport->setText(name);
+        ObjNameReport->setTextAlignment(Qt::AlignHCenter);
+        mountModel.alignTable->setItem(currentRow, 2, ObjNameReport);
 
-            QTableWidgetItem *ObjNameReport = new QTableWidgetItem();
-            ObjNameReport->setText(o->longname());
-            ObjNameReport->setTextAlignment(Qt::AlignHCenter);
-            mountModel.alignTable->setItem(currentRow, 2, ObjNameReport);
+        QTableWidgetItem *disabledBox= new QTableWidgetItem();
+        disabledBox->setFlags(Qt::ItemIsSelectable);
+        mountModel.alignTable->setItem(currentRow, 3, disabledBox);
+   }
+}
 
-            QTableWidgetItem *disabledBox= new QTableWidgetItem();
-            disabledBox->setFlags(Qt::ItemIsSelectable);
-            mountModel.alignTable->setItem(currentRow, 3, disabledBox);
-        }
+void Align::calculateAZPointsForDEC(dms dec, dms alt, dms &AZEast, dms &AZWest){
+    KStarsData *data = KStarsData::Instance();
+    GeoLocation *geo=data->geo();
+    double AZRad;
 
-    }
+    double sindec, cosdec, sinlat, coslat;
+    double sinAlt, cosAlt;
+
+    geo->lat()->SinCos( sinlat, coslat );
+    dec.SinCos( sindec, cosdec );
+    alt.SinCos( sinAlt, cosAlt );
+
+    double arg = ( sindec - sinlat*sinAlt )/( coslat*cosAlt );
+    AZRad = acos( arg );
+    AZEast.setRadians(AZRad);
+    AZWest.setRadians(2.0*dms::PI - AZRad);
 }
 
-const SkyObject* Align::getClosestAlignStar(double ra, double dec, double angle){
-    double bestDiff=360;
-    double index=-1;
-     for(int i=0;i<alignStars.size();i++){
-         QPair<QString, const SkyObject *> pair=alignStars.value(i);
-         const SkyObject *o=pair.second;
-         if( o != 0 ) {
-             double thisRADiff=qAbs(ra-(o->ra().Degrees()));
-             double thisDEDiff=qAbs(dec-(o->dec().Degrees()));
-             double thisDiff=qSqrt(thisRADiff*thisRADiff+thisDEDiff*thisDEDiff);
-             if(thisDiff<bestDiff){
-                 index=i;
-                 bestDiff=thisDiff;
+const SkyObject* Align::getWizardAlignObject(double ra, double dec, double angle){
+
+    if(mountModel.alignTypeBox->currentText()=="Any Object"){
+        double maxSearch=5.0;
+        SkyObject *o = KStarsData::Instance()->skyComposite()->objectNearest(new SkyPoint(dms(ra),dms(dec)), maxSearch );
+        return o;
+    }else if(mountModel.alignTypeBox->currentText()=="Fixed Positions")
+        return NULL;
+    else{
+
+        //If they want stars, then try to search for and return the closest Align Star in the radius first, and if that fails, return the closest Star.
+
+        double bestDiff=360;
+        double index=-1;
+         for(int i=0;i<alignStars.size();i++){
+             QPair<QString, const SkyObject *> pair=alignStars.value(i);
+             const SkyObject *o=pair.second;
+             if( o != 0 ) {
+                 double thisRADiff=qAbs(ra-(o->ra().Degrees()));
+                 double thisDEDiff=qAbs(dec-(o->dec().Degrees()));
+                 double thisDiff=qSqrt(thisRADiff*thisRADiff+thisDEDiff*thisDEDiff);
+                 if(thisDiff<bestDiff){
+                     index=i;
+                     bestDiff=thisDiff;
+                 }
              }
          }
-     }
-     if(index==-1||bestDiff>angle){
-         double maxSearch=5.0;
-         SkyObject *o = KStarsData::Instance()->skyComposite()->starNearest(new SkyPoint(dms(ra),dms(dec)), maxSearch );
-         return o;
-     }
-    QPair<QString, const SkyObject *> pair=alignStars.value(index);
-    qDebug()<<pair.first;
-    return pair.second;
+         if(index==-1||bestDiff>angle){
+             double maxSearch=5.0;
+             SkyObject *o = KStarsData::Instance()->skyComposite()->starNearest(new SkyPoint(dms(ra),dms(dec)), maxSearch );
+             return o;
+         }
+        QPair<QString, const SkyObject *> pair=alignStars.value(index);
+        return pair.second;
+    }
 }
 
 void Align::slotStarSelected(const QString selectedStar){
@@ -711,11 +790,7 @@ void Align::generateAlignStarList(){
 }
 
 bool Align::isVisible(const SkyObject *so){
-    //QList<double> limits=Ekos::Mount *mountModule()->getAltitudeLimits();
-   // if(limits.first()>30)
-   //     return (getAltitude(so) > limits.first());
-  //  else
-        return (getAltitude(so) > 30);
+        return (getAltitude(so) > mountModel.minAltBox->value());
 }
 
 double Align::getAltitude(const SkyObject *so){
@@ -924,7 +999,10 @@ bool Align::saveAlignmentPoints(const QString &path){
 
 }
 
-void Align::exportSolutionPoints(){
+void Align::exportSolutionPoints()
+{
+    if (solutionTable->rowCount() == 0)
+        return;
 
     QUrl exportFile = QFileDialog::getSaveFileUrl(KStars::Instance(), i18n("Export Solution Points"), alignURLPath, "CSV File (*.csv)");
     if (exportFile.isEmpty())   // if user presses cancel
@@ -1060,6 +1138,14 @@ void Align::moveAlignPoint(int logicalIndex, int oldVisualIndex, int newVisualIn
 
 void Align::slotMountModel(){
     generateAlignStarList();
+
+    SkyPoint spWest;
+    spWest.setAlt(30);
+    spWest.setAz(270);
+    spWest.HorizontalToEquatorial(KStars::Instance()->data()->lst(), KStars::Instance()->data()->geo()->lat());
+
+    mountModel.alignDec->setValue((int)spWest.dec().Degrees());
+
     mountModelDialog.show();
 }
 
@@ -1095,7 +1181,7 @@ void Align::slotFindAlignObject() {
            mountModel.alignTable->setItem(currentRow, 1, DECReport);
 
            QTableWidgetItem *ObjNameReport = new QTableWidgetItem();
-           ObjNameReport->setText(o->name());
+           ObjNameReport->setText(o->longname());
            ObjNameReport->setTextAlignment(Qt::AlignHCenter);
            mountModel.alignTable->setItem(currentRow, 2, ObjNameReport);
 
@@ -2066,15 +2152,19 @@ void Align::startSolving(const QString &filename, bool isGenerated)
         DECReport->setFlags(Qt::ItemIsSelectable);
         solutionTable->setItem(currentRow, 1, DECReport);
 
-        double maxrad = 1000.0/Options::zoomFactor();
+        double maxrad = 1.0;
         SkyObject *so = KStarsData::Instance()->skyComposite()->objectNearest(new SkyPoint(dms(ra*15),dms(dec)), maxrad );
+        QString name;
         if (so){
-            QTableWidgetItem *ObjNameReport = new QTableWidgetItem();
-            ObjNameReport->setText(so->name());
-            ObjNameReport->setTextAlignment(Qt::AlignHCenter);
-            ObjNameReport->setFlags(Qt::ItemIsSelectable);
-            solutionTable->setItem(currentRow, 2, ObjNameReport);
+            name = so->longname();
+        } else{
+            name = "None";
         }
+        QTableWidgetItem *ObjNameReport = new QTableWidgetItem();
+        ObjNameReport->setText(name);
+        ObjNameReport->setTextAlignment(Qt::AlignHCenter);
+        ObjNameReport->setFlags(Qt::ItemIsSelectable);
+        solutionTable->setItem(currentRow, 2, ObjNameReport);
 
         QProgressIndicator *alignIndicator = new QProgressIndicator(this);
         solutionTable->setCellWidget(currentRow, 3, alignIndicator);
diff --git a/kstars/ekos/align/align.h b/kstars/ekos/align/align.h
index 154675ae9..c52b8e3fb 100644
--- a/kstars/ekos/align/align.h
+++ b/kstars/ekos/align/align.h
@@ -627,7 +627,8 @@ private:
     void generateAlignStarList();
     bool isVisible(const SkyObject *so);
     double getAltitude(const SkyObject *so);
-    const SkyObject* getClosestAlignStar(double ra, double de, double angle);
+    const SkyObject* getWizardAlignObject(double ra, double de, double angle);
+    void calculateAZPointsForDEC(dms dec, dms alt, dms &AZEast, dms &AZWest);
 };
 
 }
diff --git a/kstars/ekos/align/align.ui b/kstars/ekos/align/align.ui
index 44952d37d..a551f6f62 100644
--- a/kstars/ekos/align/align.ui
+++ b/kstars/ekos/align/align.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>682</width>
-    <height>529</height>
+    <width>602</width>
+    <height>459</height>
    </rect>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout_19">
diff --git a/kstars/ekos/align/mountmodel.ui b/kstars/ekos/align/mountmodel.ui
index 5231cf177..9a7726917 100644
--- a/kstars/ekos/align/mountmodel.ui
+++ b/kstars/ekos/align/mountmodel.ui
@@ -6,14 +6,26 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>384</width>
-    <height>526</height>
+    <width>346</width>
+    <height>718</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Dialog</string>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
+   <property name="leftMargin">
+    <number>5</number>
+   </property>
+   <property name="topMargin">
+    <number>5</number>
+   </property>
+   <property name="rightMargin">
+    <number>5</number>
+   </property>
+   <property name="bottomMargin">
+    <number>5</number>
+   </property>
    <item>
     <widget class="QLabel" name="label">
      <property name="text">
@@ -32,55 +44,166 @@
      <property name="title">
       <string>Mount Model Wizard</string>
      </property>
-     <layout class="QHBoxLayout" name="horizontalLayout_3">
-      <item>
-       <widget class="QLabel" name="label_2">
-        <property name="text">
-         <string>Number of Points</string>
-        </property>
-       </widget>
-      </item>
-      <item>
-       <widget class="QSpinBox" name="alignPtNum">
-        <property name="minimum">
-         <number>2</number>
-        </property>
-       </widget>
-      </item>
+     <layout class="QVBoxLayout" name="verticalLayout_3">
+      <property name="leftMargin">
+       <number>3</number>
+      </property>
+      <property name="topMargin">
+       <number>3</number>
+      </property>
+      <property name="rightMargin">
+       <number>3</number>
+      </property>
+      <property name="bottomMargin">
+       <number>3</number>
+      </property>
       <item>
-       <widget class="QPushButton" name="wizardAlignB">
-        <property name="minimumSize">
-         <size>
-          <width>32</width>
-          <height>32</height>
-         </size>
-        </property>
-        <property name="maximumSize">
-         <size>
-          <width>32</width>
-          <height>32</height>
-         </size>
-        </property>
-        <property name="toolTip">
-         <string><html><head/><body><p>Automatically generate the specified number of alignment points in the table below.  They will be equally spread across the sky from 30 degrees above the horizon in the west to 30 degrees above the horizon in the east.</p></body></html></string>
+       <layout class="QHBoxLayout" name="horizontalLayout_4">
+        <property name="spacing">
+         <number>0</number>
         </property>
-        <property name="text">
-         <string/>
+        <property name="rightMargin">
+         <number>0</number>
         </property>
-       </widget>
+        <item>
+         <widget class="QLabel" name="label_2">
+          <property name="text">
+           <string># RA Points</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QSpinBox" name="alignPtNum">
+          <property name="toolTip">
+           <string><html><head/><body><p>The Number of points the wizard should generate at the chosen DEC</p></body></html></string>
+          </property>
+          <property name="minimum">
+           <number>2</number>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QLabel" name="label_3">
+          <property name="text">
+           <string>@ Dec</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QSpinBox" name="alignDec">
+          <property name="toolTip">
+           <string><html><head/><body><p>The Declination of the points that will be generated.</p></body></html></string>
+          </property>
+          <property name="minimum">
+           <number>-89</number>
+          </property>
+          <property name="maximum">
+           <number>89</number>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="wizardAlignB">
+          <property name="minimumSize">
+           <size>
+            <width>32</width>
+            <height>32</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>32</width>
+            <height>32</height>
+           </size>
+          </property>
+          <property name="toolTip">
+           <string><html><head/><body><p>Automatically generate the specified number of alignment points in the table below. They will be equally spread across the sky at the selected DEC above the minimum selected altitude.</p></body></html></string>
+          </property>
+          <property name="text">
+           <string/>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_3">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>171</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
       </item>
       <item>
-       <spacer name="horizontalSpacer_3">
-        <property name="orientation">
-         <enum>Qt::Horizontal</enum>
+       <layout class="QHBoxLayout" name="horizontalLayout_3">
+        <property name="spacing">
+         <number>0</number>
         </property>
-        <property name="sizeHint" stdset="0">
-         <size>
-          <width>171</width>
-          <height>20</height>
-         </size>
+        <property name="topMargin">
+         <number>0</number>
         </property>
-       </spacer>
+        <item>
+         <widget class="QLabel" name="label_6">
+          <property name="text">
+           <string>Min. Altitude: </string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QSpinBox" name="minAltBox">
+          <property name="maximum">
+           <number>80</number>
+          </property>
+          <property name="value">
+           <number>30</number>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QLabel" name="label_7">
+          <property name="text">
+           <string>Type:</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QComboBox" name="alignTypeBox">
+          <item>
+           <property name="text">
+            <string>Stars Only</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>Any Object</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>Fixed Positions</string>
+           </property>
+          </item>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_5">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>171</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
       </item>
      </layout>
     </widget>
@@ -91,6 +214,18 @@
       <string>Currently Visible Stars</string>
      </property>
      <layout class="QGridLayout" name="gridLayout">
+      <property name="leftMargin">
+       <number>3</number>
+      </property>
+      <property name="topMargin">
+       <number>3</number>
+      </property>
+      <property name="rightMargin">
+       <number>3</number>
+      </property>
+      <property name="bottomMargin">
+       <number>3</number>
+      </property>
       <item row="0" column="0">
        <widget class="QLabel" name="label_4">
         <property name="text">


More information about the Kstars-devel mailing list