×
INDI Library v1.8.5 Released (19 Apr 2020)

April 2020 release of INDI Library v1.8.5 introduces new drivers while providing fixes and improvements to existing devices and core framework.

ccd_simulator with transformation to telescope's HA system (Polar Alignment)

4 months 3 weeks ago
wildi
Senior Boarder
Senior Boarder
Posts: 50
Karma: 2
More
Topic Author
ccd_simulator with transformation to telescope's HA system (Polar Alignment) #50602
Hello all

motivated by the thread

Problem with polar alignment in southern hemisphere?

where Wouter said

Sorry, no progress so far. It has been cloudy in La Serena, Chile


I locally added the differential transformation from the HA to the telescope's HA system. Then I transformed back to the EQ system and fed the numbers to the gsc command.

I'm at the beginning of the investigation but farther away from the NCP the results from astrometry.net are correct. I'm looking at the details during comming days.

Finishing this small piece work means that the subsequent alignment calculations can be tested against it.

About 15 years ago I wrote a simulation which takes care of all these details. It was cumbersome to test and it took hours to verify the results. With INDI I simply point the telescope to a location, take a simulated image and feed it into astrometry.net. Results are available within minutes. Another big thanks to the INDI community.

Kind regards, wildi

The changes so far (please adjust ccd_simulator.h):
diff --git a/drivers/ccd/ccd_simulator.cpp b/drivers/ccd/ccd_simulator.cpp
index ada91d2a..e0e56bbc 100644
--- a/drivers/ccd/ccd_simulator.cpp
+++ b/drivers/ccd/ccd_simulator.cpp
@@ -111,6 +111,9 @@ bool CCDSim::SetupParms()
     polarError = SimulatorSettingsN[11].value;
     polarDrift = SimulatorSettingsN[12].value;
     rotationCW = SimulatorSettingsN[13].value;
+    //  Kwiq++
+    king_gamma = SimulatorSettingsN[14].value * 0.0174532925;
+    king_theta = SimulatorSettingsN[15].value * 0.0174532925;
 
     nbuf = PrimaryCCD.getXRes() * PrimaryCCD.getYRes() * PrimaryCCD.getBPP() / 8;
     //nbuf += 512;
@@ -168,7 +171,10 @@ bool CCDSim::initProperties()
                  0); /* PAE = Polar Alignment Error */
     IUFillNumber(&SimulatorSettingsN[12], "SIM_POLARDRIFT", "PAE Drift (minutes)", "%4.1f", 0, 6000, 0, 0);
     IUFillNumber(&SimulatorSettingsN[13], "SIM_ROTATION", "Rotation CW (degrees)", "%4.1f", -360, 360, 0, 0);
-    IUFillNumberVector(SimulatorSettingsNV, SimulatorSettingsN, 14, getDeviceName(), "SIMULATOR_SETTINGS",
+    IUFillNumber(&SimulatorSettingsN[14], "SIM_KING_GAMMA", "(NCP,TCP), deg", "%4.1f", 0, 10, 0, 0); 
+    IUFillNumber(&SimulatorSettingsN[15], "SIM_KING_THETA", "hour hangle, deg", "%4.1f", 0, 360, 0, 0);
+
+    IUFillNumberVector(SimulatorSettingsNV, SimulatorSettingsN, 16, getDeviceName(), "SIMULATOR_SETTINGS",
                        "Simulator Settings", "Simulator Config", IP_RW, 60, IPS_IDLE);
 
     // RGB Simulation
@@ -659,6 +665,7 @@ int CCDSim::DrawCcdFrame(INDI::CCDChip * targetChip)
         decDrift = (polarDrift * polarError * cos(decr)) / 3.81;
 
         // Add declination drift, if any.
+       // wildi, decr is not used in original source
         decr += decDrift / 3600.0 * 0.0174532925;
 
         //fprintf(stderr,"decPE %7.5f  cameradec %7.5f  CenterOffsetDec %4.4f\n",decPE,cameradec,decr);
@@ -692,7 +699,20 @@ int CCDSim::DrawCcdFrame(INDI::CCDChip * targetChip)
 
         if (radius > 60)
             lookuplimit = 11;
-
+       // wildi, transform to telescope coordinate system, differential form
+       // see E.S. King, or Chauvenet
+       IDLog("ori rar: %12.6f, dec: %12.6f\n", rar/0.0174532925, decr/0.0174532925 );
+        rar = currentRA * 15.0 * 0.0174532925;
+       double currentSid  = get_local_sidereal_time(7.5);
+       double currentHAr  = get_local_hour_angle(currentSid, rar/0.0174532925/15.) * 0.0174532925;
+       IDLog("currentSid: %12.6f, currentHA: %12.6f (decimal hours), currentRA: %12.6f\n", currentSid, currentHAr/0.0174532925 * 15., rar/0.0174532925);
+       IDLog("King gamma: %12.6f, King theta: %12.6f\n", king_gamma / 0.0174532925, king_theta / 0.0174532925);
+       rar -= king_gamma * sin(decr) * sin(currentHAr - king_theta) / cos(decr);
+       decr += king_gamma * cos(currentHAr - king_theta);
+        IDLog("mod ra %12.6f, dec: %12.6f\n", rar/0.0174532925, decr/0.0174532925 );
+       rad = rar / 0.0174532925;
+       cameradec = decr / 0.0174532925;
+               
         //  if this is a light frame, we need a star field drawn
         INDI::CCDChip::CCD_FRAME ftype = targetChip->getFrameType();
The following user(s) said Thank You TallFurryMan, wvreeven

Please Log in or Create an account to join the conversation.

4 months 3 weeks ago 4 months 3 weeks ago by wildi. Reason: corrected formatting
wildi
Senior Boarder
Senior Boarder
Posts: 50
Karma: 2
More
Topic Author
ccd_simulator with transformation to telescope's HA system (Polar Alignment) #50716
Hello all

in the mean time I completed the basic work on ccd_simulator and tested against a program I developed earlier to calculate the intersection of the hour angle axis with the sphere (see attachment for the code and the config file). Since I know the projection center I did not use astrometry.net solver and I could reproduce my settings within a few arcsec. I don't know yet what to blame but astrometry.net's solutions are not always optimal.

I made a few preliminary runs to check Wouter's Ekos alignment code and the angle (CP,TCP) agree reasonably but not yet fully. So far I could not check the HA of the hour axis (because Ekos does not display it).

The ccd_simulator, find the entire file attached, can only be used in <strong>real time</strong> since I do not know yet how to obtain the time from KStars (or any other suitable source).
Further the maximum angle of the HA axis intersection and the celestial pole (north or south) must not exceed 1 degree. This angle can be set in ccd simulator tab Simulator Config (see attached image) together with the hour angle of the HA axis. The reason for the 1 degree limit is not the calculation but the radius where star coordinates are retrieved from GSC.

Since I recalculate the projection center of the simulated image there might be a systematic error, the refraction. The reason is simple: I currently do not know, what INDI thinks what JNow is. If the refraction is in JNow the alignment will end up at the "refracted" CP, like in real life :-), since I apply a differential transformation.

Besides testing the polar alignment codes there is another use case for this simulator. Once the refraction is taken into account one can study field rotation or better field distortion in great detail.

EDIT: I Just learned on the list about ALS - Astro Live Stacker , a tool which makes the distortion visible.

Kind regards, wildi
diff --git a/drivers/ccd/ccd_simulator.cpp b/drivers/ccd/ccd_simulator.cpp
index ada91d2a..ef6685f5 100644
--- a/drivers/ccd/ccd_simulator.cpp
+++ b/drivers/ccd/ccd_simulator.cpp
@@ -111,6 +111,9 @@ bool CCDSim::SetupParms()
     polarError = SimulatorSettingsN[11].value;
     polarDrift = SimulatorSettingsN[12].value;
     rotationCW = SimulatorSettingsN[13].value;
+    //  Kwiq++
+    king_gamma = SimulatorSettingsN[14].value * 0.0174532925;
+    king_theta = SimulatorSettingsN[15].value * 0.0174532925;
 
     nbuf = PrimaryCCD.getXRes() * PrimaryCCD.getYRes() * PrimaryCCD.getBPP() / 8;
     //nbuf += 512;
@@ -168,7 +171,10 @@ bool CCDSim::initProperties()
                  0); /* PAE = Polar Alignment Error */
     IUFillNumber(&SimulatorSettingsN[12], "SIM_POLARDRIFT", "PAE Drift (minutes)", "%4.1f", 0, 6000, 0, 0);
     IUFillNumber(&SimulatorSettingsN[13], "SIM_ROTATION", "Rotation CW (degrees)", "%4.1f", -360, 360, 0, 0);
-    IUFillNumberVector(SimulatorSettingsNV, SimulatorSettingsN, 14, getDeviceName(), "SIMULATOR_SETTINGS",
+    IUFillNumber(&SimulatorSettingsN[14], "SIM_KING_GAMMA", "(CP,TCP), deg", "%4.1f", 0, 10, 0, 0); 
+    IUFillNumber(&SimulatorSettingsN[15], "SIM_KING_THETA", "hour hangle, deg", "%4.1f", 0, 360, 0, 0);
+
+    IUFillNumberVector(SimulatorSettingsNV, SimulatorSettingsN, 16, getDeviceName(), "SIMULATOR_SETTINGS",
                        "Simulator Settings", "Simulator Config", IP_RW, 60, IPS_IDLE);
 
     // RGB Simulation
@@ -659,6 +665,7 @@ int CCDSim::DrawCcdFrame(INDI::CCDChip * targetChip)
         decDrift = (polarDrift * polarError * cos(decr)) / 3.81;
 
         // Add declination drift, if any.
+       // wildi, decr is not used in original source
         decr += decDrift / 3600.0 * 0.0174532925;
 
         //fprintf(stderr,"decPE %7.5f  cameradec %7.5f  CenterOffsetDec %4.4f\n",decPE,cameradec,decr);
@@ -669,7 +676,6 @@ int CCDSim::DrawCcdFrame(INDI::CCDChip * targetChip)
                       (Scaley * Scaley * targetChip->getYRes() / 2.0 * targetChip->getYRes() / 2.0));
         //  we have radius in arcseconds now
         radius = radius / 60; //  convert to arcminutes
-
 #if 0
         LOGF_DEBUG("Lookup radius %4.2f", radius);
 #endif
@@ -692,7 +698,76 @@ int CCDSim::DrawCcdFrame(INDI::CCDChip * targetChip)
 
         if (radius > 60)
             lookuplimit = 11;
-
+       // wildi, make sure there are always stars, e.g. in case where king_gamma is set to 1 degree.
+       // Otherwise the solver will fail.
+       radius = 60.;
+
+       // wildi, transform to telescope coordinate system, differential form
+       // see E.S. King based on Chauvenet:
+       // https://ui.adsabs.harvard.edu/link_gateway/1902AnHar..41..153K/ADS_PDF
+       IDLog("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+       char TRAStr[64] = {0};
+       fs_sexa(TRAStr, RA, 2, 360000);
+       char TStr[64] = {0};
+       fs_sexa(TStr, Dec, 2, 360000);
+       IDLog("King gamma     : %8.3f, King theta  : %8.3f\n", king_gamma / 0.0174532925, king_theta / 0.0174532925);
+       IDLog("tel RA         : %11s,       dec: %11s\n", TRAStr, TStr );
+       IDLog("tel RA         : %8.3f, Dec         : %8.3f\n", RA * 15., Dec);
+       IDLog("tel J2000Pos.ra: %8.3f, J2000Pos.dec: %8.3f\n", J2000Pos.ra, J2000Pos.dec);
+       // Since the catalog is J2000, we  are going back in time
+       double tra = J2000Pos.ra;  // J2000Pos: 0,360, RA: 0,24
+       double tdec = J2000Pos.dec;
+       
+        double trar = tra * 0.0174532925;
+       double tdecr = tdec * 0.0174532925;
+       double sid  = get_local_sidereal_time(this->Longitude);
+       // apparent or J2000? see below
+       double JtraHAr  = get_local_hour_angle(sid, tra/15.) * 15. * 0.0174532925;
+       double TtraHAr  = get_local_hour_angle(sid, RA) * 15. * 0.0174532925;
+       
+       char sidStr[64] = {0};
+       fs_sexa(sidStr, sid, 2, 3600);
+       char traRAStr[64] = {0};
+       fs_sexa(traRAStr, tra, 2, 360000);
+       char JtraHAStr[64] = {0};
+       fs_sexa(JtraHAStr, JtraHAr / 0.0174532925, 2, 360000);
+       char TtraHAStr[64] = {0};
+       fs_sexa(TtraHAStr, TtraHAr / 0.0174532925, 2, 360000);
+       
+       IDLog("sid            : %s\n", sidStr);
+       IDLog("traRA          : %8.3f,       JtraHA: %8.3f\n", RA, JtraHAr / 0.0174532925);
+       IDLog("tel                              TtraHA: %8.3f\n", TtraHAr / 0.0174532925);
+       IDLog("J2000                         JtraHAStr: %11s\n", JtraHAStr);
+       IDLog("tel                           TtraHAStr: %11s\n", TtraHAStr);
+       // king_theta is the HA of the great circle where the HA axis is in. 
+       // RA is a right and HA a left handed coordinate system.
+       // apparent or J2000?
+       // double traHAr = JtraHAr;
+       // apparent, since we live now :-)
+       double traHAr = TtraHAr;
+       // attention: periodic error (PE) is disabled
+       // Transform to the mount coordinate system
+       trar -= king_gamma * sin(tdecr) * sin(traHAr - king_theta) / cos(tdecr);
+       // Imagine the HA axis points to HA=0, dec=89deg, then in the mount's coordinate
+       // system a star at true dec = 88 is seen at 89 deg in the mount's system
+       // Or in other words: if one uses the setting circle, that is the mount system,
+       // and set it to 87 deg then the real location is at 88 deg. 
+       tdecr += king_gamma * cos(traHAr - king_theta);
+
+       IDLog("mod sin        : %8.3f,          cos: %8.3f\n", sin(traHAr - king_theta), cos(traHAr - king_theta));
+       IDLog("mod dra        : %8.3f,         ddec: %8.3f\n", king_gamma * sin(tdecr) * sin(traHAr - king_theta) / cos(tdecr)/0.0174532925 , king_gamma * cos(traHAr - king_theta)/0.0174532925 );
+       IDLog("mod ra         : %8.3f,          dec: %8.3f\n", trar/0.0174532925 , tdecr/0.0174532925 );
+       char KtraRAStr[64] = {0};
+       fs_sexa(KtraRAStr, trar / 15. / 0.0174532925, 2, 360000);
+       char KDecStr[64] = {0};
+       fs_sexa(KDecStr, tdecr / 0.0174532925, 2, 360000);
+       IDLog("mod ra         : %s,       dec: %s\n", KtraRAStr, KDecStr );
+       
+       // again attention: periodic error (PE) is disabled
+       rad = trar / 0.0174532925;
+       cameradec = tdecr / 0.0174532925;
+
+       
         //  if this is a light frame, we need a star field drawn
         INDI::CCDChip::CCD_FRAME ftype = targetChip->getFrameType();
 
@@ -709,7 +784,8 @@ int CCDSim::DrawCcdFrame(INDI::CCDChip * targetChip)
             int drawn = 0;
 
             sprintf(gsccmd, "gsc -c %8.6f %+8.6f -r %4.1f -m 0 %4.2f -n 3000",
-                    range360(rad + PEOffset),
+                    //range360(rad + PEOffset),
+                    range360(rad),
                     rangeDec(cameradec),
                     radius,
                     lookuplimit);
@@ -717,6 +793,7 @@ int CCDSim::DrawCcdFrame(INDI::CCDChip * targetChip)
             if (!Streamer->isStreaming())
                 LOGF_DEBUG("GSC Command: %s", gsccmd);
 
+           IDLog("--->GSC Command: %s\n", gsccmd);
             pp = popen(gsccmd, "r");
             if (pp != nullptr)
             {
@@ -760,9 +837,11 @@ int CCDSim::DrawCcdFrame(INDI::CCDChip * targetChip)
 
                         //fprintf(stderr,"line %s",line);
                         //fprintf(stderr,"parsed %6.5f %6.5f\n",ra,dec);
-
                         srar  = ra * 0.0174532925;
                         sdecr = dec * 0.0174532925;
+                       // wildi, projection center is the "king's center" (mount coordinate system)
+                        rar  = trar ;
+                        decr = tdecr ;
                         //  Handbook of astronomical image processing
                         //  page 253
                         //  equations 9.1 and 9.2

Attachments:

Please Log in or Create an account to join the conversation.

4 months 3 weeks ago
wvreeven
Platinum Boarder
Platinum Boarder
Posts: 1574
Karma: 8
More
ccd_simulator with transformation to telescope's HA system (Polar Alignment) #50758
Great work! FYI it is not my alignment code :silly:

ASI6200 and filter wheel with a SkyWatcher Esprit 80 ED on a SkyWatcher HEQ5-Pro
ASI1600MM-Pro Cooled and filter wheel with an 8" TS Ritchey-Chrétien on a SkyWatcher EQ6-R

Please Log in or Create an account to join the conversation.

Time to create page: 0.160 seconds