From cf28ecc7c29bc76e57a4dc2d0801a23e14e0ea4e Mon Sep 17 00:00:00 2001 From: Colin Date: Sat, 18 May 2019 23:50:55 +0100 Subject: [PATCH] Redesigned the Altitude and Azimuth readings to use the Right Ascension and Declination co-ordinates and perform the transformation using the date and site details from the scope. This will correct the problem of the Altitude reading from the handset being incorrect. --- .../AstroMath.UnitTests.csproj | 83 +++++++++ AstroMath.UnitTests/AstroMathsUnitTests.cs | 149 ++++++++++++++++ .../Properties/AssemblyInfo.cs | 36 ++++ AstroMath.UnitTests/packages.config | 8 + Meade.net.Telescope/AstroMaths.cs | 165 ++++++++++++++++++ .../Meade.net.Telescope.csproj | 1 + Meade.net.Telescope/Telescope.cs | 56 ++++-- Meade.net.sln | 17 +- TelescopeTestConsole/Program.cs | 10 +- 9 files changed, 506 insertions(+), 19 deletions(-) create mode 100644 AstroMath.UnitTests/AstroMath.UnitTests.csproj create mode 100644 AstroMath.UnitTests/AstroMathsUnitTests.cs create mode 100644 AstroMath.UnitTests/Properties/AssemblyInfo.cs create mode 100644 AstroMath.UnitTests/packages.config create mode 100644 Meade.net.Telescope/AstroMaths.cs diff --git a/AstroMath.UnitTests/AstroMath.UnitTests.csproj b/AstroMath.UnitTests/AstroMath.UnitTests.csproj new file mode 100644 index 0000000..2004ecf --- /dev/null +++ b/AstroMath.UnitTests/AstroMath.UnitTests.csproj @@ -0,0 +1,83 @@ + + + + + + Debug + AnyCPU + {AD4959DD-33D7-4C3F-8DB0-7361D8E74A95} + Library + Properties + AstroMath.UnitTests + AstroMath.UnitTests + v4.7.2 + 512 + true + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + x86 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll + + + ..\packages\Moq.4.10.1\lib\net45\Moq.dll + + + ..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll + + + + + + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + + + ..\packages\System.Threading.Tasks.Extensions.4.5.1\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll + + + + + + + + + + + + + + + {64308775-bd4a-469c-bcab-3ed830b811af} + Meade.net.Telescope + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/AstroMath.UnitTests/AstroMathsUnitTests.cs b/AstroMath.UnitTests/AstroMathsUnitTests.cs new file mode 100644 index 0000000..f4792d3 --- /dev/null +++ b/AstroMath.UnitTests/AstroMathsUnitTests.cs @@ -0,0 +1,149 @@ +using System; +using ASCOM.Meade.net; +using NUnit.Framework; + +namespace AstroMath.UnitTests +{ + [TestFixture] + public class AstroMathsUnitTests + { + private AstroMaths _astroMath; + + [SetUp] + public void Setup() + { + _astroMath = new AstroMaths(); + } + + [Test] + public void DegreesToRadians() + { + var radians = _astroMath.DegreesToRadians(90); + Assert.That(radians, Is.EqualTo(1.5707963267948966)); + } + + [Test] + public void RadiansToDegrees() + { + var degrees = _astroMath.RadiansToDegrees(1.5707963267948966); + Assert.That(degrees, Is.EqualTo(90)); + } + + + [Test] + public void DateTimeToDecimalHours_book() + { + DateTime dateTime = new DateTime(2019, 05, 18, 18, 31, 27, DateTimeKind.Utc); + var decimalHours = _astroMath.DateTimeToDecimalHours(dateTime); + + Assert.That(decimalHours, Is.EqualTo(18.524166666666666)); + } + + [Test] + public void DateTimeToDecimalHours() + { + DateTime dateTime = new DateTime(2019, 05, 18, 22, 26, 15, DateTimeKind.Utc); + var decimalHours = _astroMath.DateTimeToDecimalHours(dateTime); + + Assert.That(decimalHours, Is.EqualTo(22.4375)); + } + + [Test] + public void UTtoGST_book() + { + DateTime dateTime = new DateTime(1980, 04, 22, 14, 36, 51, 670, DateTimeKind.Utc); + double gst = _astroMath.UTtoGST(dateTime); + + Assert.That(gst, Is.EqualTo(4.667932706211154)); + } + + [Test] + public void UTtoGST() + { + DateTime dateTime = new DateTime(2019, 05, 18, 22, 26, 15, DateTimeKind.Utc); + double gst = _astroMath.UTtoGST(dateTime); + + Assert.That(gst, Is.EqualTo(14.191879687876451)); + } + + [Test] + public void GSTtoLST_book() + { + double gst = 4.668119; + var longitude = -64; + var lst = _astroMath.GSTtoLST(gst, longitude); + Assert.That(lst, Is.EqualTo(0.4014523333333333)); + } + + [Test] + public void GSTtoLST() + { + double gst = 14.257589512545053; + var longitude = -1.7833333333333332; + var lst = _astroMath.GSTtoLST(gst, longitude); + Assert.That(lst, Is.EqualTo(14.138700623656163)); + } + + [Test] + public void RightAscensionToHourAngle_book() + { + DateTime dateTime = new DateTime(1980, 04, 22, 18, 36, 51,670, DateTimeKind.Utc); + var longitude = -64; + var rightAscension = 18.539166666666667;//18:32'21" + + //var declination = 30.0019444444444 + var hourAngle = _astroMath.RightAscensionToHourAngle(dateTime, longitude, rightAscension); + Assert.That(hourAngle, Is.EqualTo(9.8730510088778161)); + } + + [Test] + public void RightAscensionToHourAngle() + { + DateTime dateTime = new DateTime(2019, 05, 18, 22, 26, 15, DateTimeKind.Utc); + var longitude = -1.7833333333333332; + var rightAscension = 4.15361111111111; + + var hourAngle = _astroMath.RightAscensionToHourAngle(dateTime, longitude, rightAscension); + Assert.That(hourAngle, Is.EqualTo(9.9193796878764502)); + } + + + [Test] + public void ConvertEqToHoz_book() + { + DateTime dateTime = new DateTime(2019, 05, 18, 22, 26, 15, DateTimeKind.Utc); + var longitude = -1.7833333333333332; + var latitude = 52.0; + + EquatorialCoordinates equatorialCoordinates = new EquatorialCoordinates(); + equatorialCoordinates.RightAscension = 5.862222222222222;//5 51' 44" + equatorialCoordinates.Declination = 23.21944444444444;//23 13' 10" + + //var hourAngle = _astroMath.RightAscensionToHourAngle(dateTime, longitude, equatorialCoordinates.RightAscension); + var hourAngle = 5.682222; + + var altAz = _astroMath.ConvertEqToHoz(hourAngle, latitude, equatorialCoordinates); + + Assert.That(altAz.Altitude, Is.EqualTo(20.958562421092779)); + Assert.That(altAz.Azimuth, Is.EqualTo(281.2728706962269)); + } + + [Test] + public void ConvertEqToHoz() + { + DateTime dateTime = new DateTime(2019, 05, 18, 22, 26, 15, DateTimeKind.Utc); + var longitude = -1.7833333333333332; + var latitude = 52.0; + EquatorialCoordinates equatorialCoordinates = new EquatorialCoordinates(); + equatorialCoordinates.RightAscension = 4.15361111111111; + equatorialCoordinates.Declination = 30.0019444444444; + + var hourAngle = _astroMath.RightAscensionToHourAngle(dateTime, longitude, equatorialCoordinates.RightAscension); + var altaz = _astroMath.ConvertEqToHoz(hourAngle, latitude, equatorialCoordinates); + + Assert.That(altaz.Altitude, Is.EqualTo(-3.5534402923925872)); + Assert.That(altaz.Azimuth, Is.EqualTo(333.2819484462679)); + } + + } +} diff --git a/AstroMath.UnitTests/Properties/AssemblyInfo.cs b/AstroMath.UnitTests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..11e0a8b --- /dev/null +++ b/AstroMath.UnitTests/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("AstroMath.UnitTests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("AstroMath.UnitTests")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("ad4959dd-33d7-4c3f-8db0-7361d8e74a95")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/AstroMath.UnitTests/packages.config b/AstroMath.UnitTests/packages.config new file mode 100644 index 0000000..22d8680 --- /dev/null +++ b/AstroMath.UnitTests/packages.config @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Meade.net.Telescope/AstroMaths.cs b/Meade.net.Telescope/AstroMaths.cs new file mode 100644 index 0000000..d9d224e --- /dev/null +++ b/Meade.net.Telescope/AstroMaths.cs @@ -0,0 +1,165 @@ +using System; +using ASCOM.Utilities; + +namespace ASCOM.Meade.net +{ + public class EquatorialCoordinates + { + public double RightAscension { get; set; } + public double Declination { get; set; } + } + + public class HorizonCoordinates + { + public double Altitude { get; set; } + public double Azimuth { get; set; } + } + + + public class AltitudeData + { + public DateTime UtcDateTime { get; set; } + public double SiteLatitude { get; set; } + public double SiteLongitude { get; set; } + public EquatorialCoordinates equatorialCoordinates { get; set; } + } + + public class AstroMaths + { + + //returns the decimal hour angle for given right ascension on a given datetime for a given logitude. + public double RightAscensionToHourAngle(DateTime utcDateTime, double longitude, double rightAscension) + { + var ut = DateTimeToDecimalHours( utcDateTime); + var gst = UTtoGST( utcDateTime); + var lst = GSTtoLST( gst, longitude); + var raHours = rightAscension; + var h1 = lst - raHours; + var h = h1; + + if (h < 0) + h = h + 24; + + return h; + } + + public HorizonCoordinates ConvertEqToHoz(double hourAngle, double latitude, EquatorialCoordinates raDec) + { + var h = hourAngle * 15; + var h1 = DegreesToRadians(h); + var d = DegreesToRadians(raDec.Declination); + var lat = DegreesToRadians(latitude); + var sinA = Math.Sin(d) * Math.Sin(lat) + Math.Cos(d) * Math.Cos(lat) * Math.Cos(h1); + + var y = -Math.Cos(d) * Math.Cos(lat) * Math.Sin(h1); + var x = Math.Sin(d) - Math.Sin(lat) * sinA; + var upperA = Math.Atan2(y, x); + var upperB = RadiansToDegrees(upperA); + + var horizonCoordinates = new HorizonCoordinates(); + horizonCoordinates.Altitude = RadiansToDegrees(Math.Asin(sinA)); + + horizonCoordinates.Azimuth = upperB; + + if (upperB < 0) + { + horizonCoordinates.Azimuth = 360 + horizonCoordinates.Azimuth; + } + + return horizonCoordinates; + } + + + //todo convert to extension method + public double DegreesToRadians(double degrees) + { + return (Math.PI / 180) * degrees; + } + + //todo convert to extension method + public double RadiansToDegrees(double radians) + { + double degrees = (180 / Math.PI) * radians; + return (degrees); + } + + //todo convert to extension method + public double DateTimeToDecimalHours( DateTime utcDateTime) + { + double sec = utcDateTime.Second; + double min = utcDateTime.Minute; + double hour = utcDateTime.Hour; + + var a = Math.Abs(sec) / 60; + var b = (Math.Abs(min) + a) / 60; + var c = Math.Abs(hour) + b; + + var d = c; + + if ((hour < 0) || (min < 0) || (sec < 0)) + d = -c; + + return d; + } + + //todo convert to extension method + public double UTtoGST(DateTime utcDateTime) + { + Util util = new Util(); + + var jd = util.DateUTCToJulian(utcDateTime) - 0.5; + if ((jd % 1) <= 0.5 ) + jd = Math.Floor( jd ); + else + jd = Math.Floor( jd ) + 0.5; + + var s = jd - 2451545.0; + var t = s / 36525.0; + var t0 = 6.697374558 + (2400.051336 * t ) +(0.000025862 * (t * t) ); + + while (t0 < 0) + { + t0 += 24; + } + + while (t0 >= 24) + { + t0 -= 24; + } + + var ut = DateTimeToDecimalHours(utcDateTime); + var a = ut * 1.002737909; + + var t1 = t0 + a; + + while (t1 < 0) + { + t1 += 24; + } + + while (t1 >= 24) + { + t1 -= 24; + } + + return t1; + } + + public double GSTtoLST(double gst, double longitude) + { + var l = longitude/ 15; + + var lst = gst + l; + while (lst < 0 ) + { + lst += 24; + } + while (lst >= 24) + { + lst -= 24; + } + + return lst; + } + } +} diff --git a/Meade.net.Telescope/Meade.net.Telescope.csproj b/Meade.net.Telescope/Meade.net.Telescope.csproj index dbf6b21..9e74b40 100644 --- a/Meade.net.Telescope/Meade.net.Telescope.csproj +++ b/Meade.net.Telescope/Meade.net.Telescope.csproj @@ -81,6 +81,7 @@ + diff --git a/Meade.net.Telescope/Telescope.cs b/Meade.net.Telescope/Telescope.cs index 11762d1..2829e4e 100644 --- a/Meade.net.Telescope/Telescope.cs +++ b/Meade.net.Telescope/Telescope.cs @@ -98,6 +98,8 @@ namespace ASCOM.Meade.net /// private AstroUtils astroUtilities; + private AstroMaths astroMaths; + /// /// Variable to hold the trace logger object (creates a diagnostic log file with information that you specify) /// @@ -117,7 +119,9 @@ namespace ASCOM.Meade.net connectedState = false; // Initialise connected to false utilities = new Util(); //Initialise util object astroUtilities = new AstroUtils(); // Initialise astro utilities object + //TODO: Implement your additional construction here + astroMaths = new AstroMaths(); tl.LogMessage("Telescope", "Completed initialisation"); } @@ -403,21 +407,45 @@ namespace ASCOM.Meade.net { get { - //todo firmware bug in 44Eg, :GA# is returning the dec, not the altitude! - var result = SharedResources.SendString(":GA#"); - //:GA# Get Telescope Altitude - //Returns: sDD* MM# or sDD*MM’SS# - //The current scope altitude. The returned format depending on the current precision setting. + var altAz = CalcAltAzFromTelescopeEqData(); + tl.LogMessage("Altitude", $"{altAz.Altitude}"); + return altAz.Altitude; - var alt = utilities.DMSToDegrees(result); - tl.LogMessage("Altitude", $"{alt}"); - return alt; + ////todo firmware bug in 44Eg, :GA# is returning the dec, not the altitude! + //var result = SharedResources.SendString(":GA#"); + ////:GA# Get Telescope Altitude + ////Returns: sDD* MM# or sDD*MM’SS# + ////The current scope altitude. The returned format depending on the current precision setting. + + //var alt = utilities.DMSToDegrees(result); + //tl.LogMessage("Altitude", $"{alt}"); + //return alt; //tl.LogMessage("Altitude Get", "Not implemented"); //throw new ASCOM.PropertyNotImplementedException("Altitude", false); } } + private HorizonCoordinates CalcAltAzFromTelescopeEqData() + { + var altitudeData = SharedResources.Lock(() => new AltitudeData + { + UtcDateTime = this.UTCDate, + SiteLongitude = this.SiteLongitude, + SiteLatitude = this.SiteLatitude, + equatorialCoordinates = new EquatorialCoordinates() + { + RightAscension = this.RightAscension, + Declination = this.Declination + } + }); + + double hourAngle = astroMaths.RightAscensionToHourAngle(altitudeData.UtcDateTime, altitudeData.SiteLongitude, + altitudeData.equatorialCoordinates.RightAscension); + var altAz = astroMaths.ConvertEqToHoz(hourAngle, altitudeData.SiteLatitude, altitudeData.equatorialCoordinates); + return altAz; + } + public double ApertureArea { get @@ -467,15 +495,19 @@ namespace ASCOM.Meade.net { get { - var result = SharedResources.SendString(":GZ#"); + //var result = SharedResources.SendString(":GZ#"); //:GZ# Get telescope azimuth //Returns: DDD*MM#T or DDD*MM’SS# //The current telescope Azimuth depending on the selected precision. - double az = utilities.DMSToDegrees(result); + //double az = utilities.DMSToDegrees(result); - tl.LogMessage("Azimuth Get", $"{az}"); - return az; + //tl.LogMessage("Azimuth Get", $"{az}"); + //return az; + + var altAz = CalcAltAzFromTelescopeEqData(); + tl.LogMessage("Azimuth Get", $"{altAz.Azimuth}"); + return altAz.Azimuth; } } diff --git a/Meade.net.sln b/Meade.net.sln index 4ca39e2..1c77465 100644 --- a/Meade.net.sln +++ b/Meade.net.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28307.136 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28803.452 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Meade.net", "Meade.net\Meade.net.csproj", "{3689A2CB-94C5-4012-A5CF-7E7D1DD27143}" EndProject @@ -15,6 +15,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FocuserTestConsole", "Focus EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TestConsoles", "TestConsoles", "{BF650D97-AF98-4638-9C55-21311C6D88DA}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UnitTests", "UnitTests", "{0958D817-269C-44BE-BEFB-F3E6A409DE91}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AstroMath.UnitTests", "AstroMath.UnitTests\AstroMath.UnitTests.csproj", "{AD4959DD-33D7-4C3F-8DB0-7361D8E74A95}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -59,6 +63,14 @@ Global {AABC96B8-C462-4B3A-9B5F-2929E3CB7A49}.Release|Any CPU.ActiveCfg = Release|x86 {AABC96B8-C462-4B3A-9B5F-2929E3CB7A49}.Release|x86.ActiveCfg = Release|x86 {AABC96B8-C462-4B3A-9B5F-2929E3CB7A49}.Release|x86.Build.0 = Release|x86 + {AD4959DD-33D7-4C3F-8DB0-7361D8E74A95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AD4959DD-33D7-4C3F-8DB0-7361D8E74A95}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AD4959DD-33D7-4C3F-8DB0-7361D8E74A95}.Debug|x86.ActiveCfg = Debug|Any CPU + {AD4959DD-33D7-4C3F-8DB0-7361D8E74A95}.Debug|x86.Build.0 = Debug|Any CPU + {AD4959DD-33D7-4C3F-8DB0-7361D8E74A95}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AD4959DD-33D7-4C3F-8DB0-7361D8E74A95}.Release|Any CPU.Build.0 = Release|Any CPU + {AD4959DD-33D7-4C3F-8DB0-7361D8E74A95}.Release|x86.ActiveCfg = Release|Any CPU + {AD4959DD-33D7-4C3F-8DB0-7361D8E74A95}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -66,6 +78,7 @@ Global GlobalSection(NestedProjects) = preSolution {D5207217-61C7-4E94-8097-91DBACE57D2A} = {BF650D97-AF98-4638-9C55-21311C6D88DA} {AABC96B8-C462-4B3A-9B5F-2929E3CB7A49} = {BF650D97-AF98-4638-9C55-21311C6D88DA} + {AD4959DD-33D7-4C3F-8DB0-7361D8E74A95} = {0958D817-269C-44BE-BEFB-F3E6A409DE91} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3C0509DC-C7F5-48DC-920D-DCFD9C879BD2} diff --git a/TelescopeTestConsole/Program.cs b/TelescopeTestConsole/Program.cs index 72b790c..a8de179 100644 --- a/TelescopeTestConsole/Program.cs +++ b/TelescopeTestConsole/Program.cs @@ -43,12 +43,12 @@ namespace ASCOM // TODO add more code to test the driver. device.Connected = true; - //Console.WriteLine($"Altitute {device.Altitude}"); - - //Console.WriteLine($"Dec {device.Declination}"); - - device.SlewToAltAz(30, 45); + Console.WriteLine($"Ra {device.RightAscension}"); + Console.WriteLine($"Dec {device.Declination}"); + Console.WriteLine($"Altitude {device.Altitude}"); + Console.WriteLine($"Azimuth {device.Azimuth}"); + device.Connected = false; Console.WriteLine("Press Enter to finish"); Console.ReadLine();