Skip to content

Commit 47e1dff

Browse files
Merged in Peter's fix for Telescope RightAscensionRate bug
1 parent 43a2d53 commit 47e1dff

File tree

1 file changed

+41
-18
lines changed

1 file changed

+41
-18
lines changed

TelescopeSimulator/TelescopeHardware.cs

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
using ASCOM.Common;
2222
using ASCOM.Common.DeviceInterfaces;
2323
using ASCOM.Common.Interfaces;
24+
using ASCOM.Tools;
2425
using System;
2526
using System.Collections.Concurrent;
2627
using System.Collections.Generic;
@@ -68,10 +69,13 @@ public static class TelescopeHardware
6869
private const double SOLAR_RATE_DEG_SEC = 15.0 / 3600;
6970
private const double LUNAR_RATE_DEG_SEC = 14.515 / 3600;
7071
private const double KING_RATE_DEG_SEC = 15.037 / 3600;
71-
private const double DEGREES_TO_ARCSEC = 3600.0;
72-
private const double ARCSEC_TO_DEGREES = 1.0 / DEGREES_TO_ARCSEC;
73-
private const double SIDEREAL_SECONDS_TO_SI_SECONDS = 0.9972695601852;
72+
private const double DEGREES_TO_ARCSECONDS = 3600.0;
73+
private const double ARCSECONDS_TO_DEGREES = 1.0 / DEGREES_TO_ARCSECONDS;
74+
private const double ARCSECONDS_PER_RA_SECOND = 15.0; // To convert "seconds of RA" (24 hours = a whole circle) to arc seconds (360 degrees = a whole circle)
75+
private const double SIDEREAL_SECONDS_TO_SI_SECONDS = 0.99726956631945;
7476
private const double SI_SECONDS_TO_SIDEREAL_SECONDS = 1.0 / SIDEREAL_SECONDS_TO_SI_SECONDS;
77+
private const double SIDEREAL_RATE_DEG_PER_SIDEREAL_SECOND = 360.0 / (24.0 * 60.0 * 60.0); // Degrees per sidereal second, given the earth's rotation of 360 degrees in 1 sidereal day
78+
private const double SIDEREAL_RATE_DEG_PER_SI_SECOND = SIDEREAL_RATE_DEG_PER_SIDEREAL_SECOND / SIDEREAL_SECONDS_TO_SI_SECONDS; // Degrees per SI second
7579

7680
#endregion Constants
7781

@@ -663,24 +667,32 @@ private static void MoveAxes()
663667
// Determine the changes in current axis position and target axis position required as a result of tracking
664668
if (Tracking) // Tracking is enabled
665669
{
666-
double haChange = GetTrackingChange(timeInSecondsSinceLastUpdate); // Find the hour angle change that occurred during this interval
670+
double haChange = GetTrackingChangeInDegrees(timeInSecondsSinceLastUpdate); // Find the hour angle change (in degrees )that occurred during this interval
667671
switch (alignmentMode)
668672
{
669673
case AlignmentMode.GermanPolar: // In polar aligned mounts an HA change moves only the RA (primary) axis so update this, no change is required to the Dec (secondary) axis
670674
case AlignmentMode.Polar:
671-
change.X = haChange; // Set the change in the RA (primary) current axis position due to tracking
675+
change.X = haChange; // Set the change in the RA (primary) current axis position due to tracking
672676
targetAxes.X += haChange; // Update the slew target's RA (primary) axis position that will also have changed due to tracking
673677
break;
674-
675678
case AlignmentMode.AltAz: // In Alt/Az aligned mounts the HA change moves both RA (primary) and Dec (secondary) axes so both need to be updated
676679
change = ConvertRateToAltAz(haChange); // Set the change in the Azimuth (primary) and Altitude (secondary) axis positions due to tracking
677680
targetAxes = MountFunctions.ConvertRaDecToAxes(targetRaDec, false); // Update the slew target's Azimuth (primary) and Altitude (secondary) axis positions that will also have changed due to tracking
678681
break;
679682
}
680683

681-
// We are tracking so apply any RightAScensionRate and DeclinationRate rate offsets, this assumes a polar mount.
684+
// We are tracking so apply any RightAScensionRate and DeclinationRate rate offsets, this assumes a polar mount.
682685
// This correction is not applied when MoveAxis is in effect because the interface specification says it is one or the other of these and not both at the same time
686+
Vector changePreOffset = change;
683687
change += Vector.Multiply(rateRaDecOffsetInternal, timeInSecondsSinceLastUpdate);
688+
689+
TL.LogMessage(LogLevel.Verbose, "MoveAxes", $"Time since last update: {timeInSecondsSinceLastUpdate} seconds. " +
690+
$"Mount RA normal tracking movment: {changePreOffset.X} degrees. " +
691+
$"RA normal tracking movement rate {changePreOffset.X * DEGREES_TO_ARCSECONDS / timeInSecondsSinceLastUpdate} arcseconds per SI second. " +
692+
$"Length of sideral day at this tracking rate = {Utilities.HoursToHMS(1.0 / (changePreOffset.X / timeInSecondsSinceLastUpdate) * (360.0 / 3600.0), ":", ":", "", 3)}. hh:mm:ss.xxx" +
693+
$"RightAscensionRate additional movement: {rateRaDecOffsetInternal.X * timeInSecondsSinceLastUpdate} degrees. " +
694+
$"RA movement rate including any RightAscensionrate additional movement: {change.X * DEGREES_TO_ARCSECONDS / timeInSecondsSinceLastUpdate} arcseconds per SI second. "
695+
);
684696
}
685697
}
686698

@@ -705,7 +717,7 @@ private static void MoveAxes()
705717
// update the displayed values
706718
UpdatePositions();
707719

708-
// check and update slew state
720+
// check and update slew state
709721
switch (SlewState)
710722
{
711723
case SlewType.SlewSettle:
@@ -1280,7 +1292,7 @@ public static double DeclinationRate
12801292
set
12811293
{
12821294
rateRaDecOffsetExternal.Y = value; // Save the provided rate to be returned through the Get property
1283-
rateRaDecOffsetInternal.Y = value * ARCSEC_TO_DEGREES; // Save the rate in the internal units that the simulator uses
1295+
rateRaDecOffsetInternal.Y = value * ARCSECONDS_TO_DEGREES; // Save the rate in the internal units that the simulator uses
12841296
}
12851297
}
12861298

@@ -1367,14 +1379,28 @@ public static int DateDelta
13671379
}
13681380
}
13691381

1370-
// converts the rate between seconds per sidereal second and seconds per second
1382+
/// <summary>
1383+
/// Manages RightAscensionRate. Units are "seconds of RA per sidereal second".
1384+
/// </summary>
1385+
/// <remarks>
1386+
/// 1) This property retains the value supplied by set RightAscensionRate in the rateRaDecOffsetExternal.X vector element so that it can be returned by get RightAscensionRate.
1387+
/// 2) The set RightAscensionRate value is also converted to the internal units used by the simulator (arcsec per SI second) and stored in the rateRaDecOffsetInternal.X vector element
1388+
/// </remarks>
13711389
public static double RightAscensionRate
13721390
{
13731391
get { return rateRaDecOffsetExternal.X; }
13741392
set
13751393
{
1376-
rateRaDecOffsetExternal.X = value; // Save the provided rate to be returned through the Get property
1377-
rateRaDecOffsetInternal.X = value * SIDEREAL_SECONDS_TO_SI_SECONDS * ARCSEC_TO_DEGREES; // Save the rate in the internal units that the simulator uses
1394+
// Save the provided rate (seconds of RA per sidereal second) to be returned through the Get property
1395+
rateRaDecOffsetExternal.X = value;
1396+
1397+
// Save the provided rate for internal use in the units (degrees per SI second) that the simulator uses.
1398+
// SIDEREAL_SECONDS_TO_SI_SECONDS converts from sidereal seconds to SI seconds
1399+
// Have to divide by the SIDEREAL_SECONDS_TO_SI_SECONDS conversion factor (0.99726956631945) because SI seconds are longer than sidereal seconds and hence the simulator movement will be greater in one SI second than in one sidereal second
1400+
// ARCSECONDS_PER_RA_SECOND converts from seconds of RA (1 circle = 24 hours) to arcseconds (1 circle = 360 degrees)
1401+
// ARCSECONDS_TO_DEGREES converts from arc seconds to degrees
1402+
rateRaDecOffsetInternal.X = (value / SIDEREAL_SECONDS_TO_SI_SECONDS) * ARCSECONDS_PER_RA_SECOND * ARCSECONDS_TO_DEGREES;
1403+
TL.LogMessage(LogLevel.Information, "RightAscensionRate Set", $"Value to be set (as received): {value} seconds per sidereal second. Converted to internal rate of: {value / SIDEREAL_SECONDS_TO_SI_SECONDS} seconds per SI second = {rateRaDecOffsetInternal.X} degrees per SI second.");
13781404
}
13791405
}
13801406

@@ -1613,11 +1639,11 @@ internal static void LogMessage(string identifier, string format, params object[
16131639
}
16141640

16151641
/// <summary>
1616-
/// returns the mount traacking movement in hour angle during the update intervaaal
1642+
/// returns the mount tracking movement in hour angle during the update interval
16171643
/// </summary>
16181644
/// <param name="updateInterval">The update interval.</param>
16191645
/// <returns></returns>
1620-
private static double GetTrackingChange(double updateInterval)
1646+
private static double GetTrackingChangeInDegrees(double updateInterval)
16211647
{
16221648
if (!Tracking)
16231649
{
@@ -1630,17 +1656,14 @@ private static double GetTrackingChange(double updateInterval)
16301656
switch (TrackingRate)
16311657
{
16321658
case DriveRate.Sidereal:
1633-
haChange = SIDEREAL_RATE_DEG_SEC * updateInterval; // change in degrees
1659+
haChange = SIDEREAL_RATE_DEG_PER_SI_SECOND * updateInterval; // change in degrees
16341660
break;
1635-
16361661
case DriveRate.Solar:
16371662
haChange = SOLAR_RATE_DEG_SEC * updateInterval; // change in degrees
16381663
break;
1639-
16401664
case DriveRate.Lunar:
16411665
haChange = LUNAR_RATE_DEG_SEC * updateInterval; // change in degrees
16421666
break;
1643-
16441667
case DriveRate.King:
16451668
haChange = KING_RATE_DEG_SEC * updateInterval; // change in degrees
16461669
break;

0 commit comments

Comments
 (0)