예제 #1
0
        public ViewportFoV(Coordinates centerCoordinates, double vFoVDegrees, double width, double height, double rotation)
        {
            Rotation = rotation;

            OriginalWidth  = width;
            OriginalHeight = height;

            Width  = width;
            Height = height;

            OriginalVFoV = vFoVDegrees;
            OriginalHFoV = (vFoVDegrees / height) * width;

            ArcSecWidth  = Astrometry.DegreeToArcsec(OriginalHFoV) / OriginalWidth;
            ArcSecHeight = Astrometry.DegreeToArcsec(OriginalVFoV) / OriginalHeight;

            CenterCoordinates = centerCoordinates;

            ViewPortCenterPoint = new Point(width / 2, height / 2);

            Shift(new Vector(0, 0));

            horizontalBoundsPadding = Width / 6;
            verticalBoundsPadding   = Height / 6;
        }
예제 #2
0
        public void DegreeToArcsec_ValueTest()
        {
            var degree         = 180;
            var expectedarcsec = 648000;

            var arcsec = Astrometry.DegreeToArcsec(degree);

            Assert.AreEqual(expectedarcsec, arcsec);
        }
예제 #3
0
파일: AngleTest.cs 프로젝트: daleghent/NINA
        public void CreateByRadiansTest(double inputRadians)
        {
            var angle = Angle.ByRadians(inputRadians);

            var expectedDegree = Astrometry.ToDegree(inputRadians);
            var expectedArcmin = Astrometry.DegreeToArcmin(expectedDegree);
            var expectedArcsec = Astrometry.DegreeToArcsec(expectedDegree);
            var expectedHours  = Astrometry.DegreesToHours(expectedDegree);

            Assert.AreEqual(expectedHours, angle.Hours, TOLERANCE);
            Assert.AreEqual(inputRadians, angle.Radians, TOLERANCE);
            Assert.AreEqual(expectedDegree, angle.Degree, TOLERANCE);
            Assert.AreEqual(expectedArcmin, angle.ArcMinutes, TOLERANCE);
            Assert.AreEqual(expectedArcsec, angle.ArcSeconds, TOLERANCE);
        }
예제 #4
0
        private string Deg2str(double deg, int precision)
        {
            if (Math.Abs(deg) > 1)
            {
                return(deg.ToString("N" + precision) + "° (degree)");
            }
            var amin = Astrometry.DegreeToArcmin(deg);

            if (Math.Abs(amin) > 1)
            {
                return(amin.ToString("N" + precision) + "' (arcmin)");
            }
            var asec = Astrometry.DegreeToArcsec(deg);

            return(asec.ToString("N" + precision) + "'' (arcsec)");
        }
예제 #5
0
파일: AngleTest.cs 프로젝트: daleghent/NINA
        public void OperatorMultiplyDoubleTest(double firstDegree, double secondDegree)
        {
            var secondAngle = Angle.ByDegree(secondDegree);

            var angle = Astrometry.ToRadians(firstDegree) * secondAngle;

            var expectedRadian = Astrometry.ToRadians(firstDegree) * Astrometry.ToRadians(secondDegree);
            var expectedDegree = Astrometry.ToDegree(expectedRadian);
            var expectedArcmin = Astrometry.DegreeToArcmin(expectedDegree);
            var expectedArcsec = Astrometry.DegreeToArcsec(expectedDegree);
            var expectedHours  = Astrometry.DegreesToHours(expectedDegree);

            Assert.AreEqual(expectedDegree, angle.Degree, TOLERANCE);
            Assert.AreEqual(expectedArcmin, angle.ArcMinutes, TOLERANCE);
            Assert.AreEqual(expectedArcsec, angle.ArcSeconds, TOLERANCE);
            Assert.AreEqual(expectedHours, angle.Hours, TOLERANCE);
            Assert.AreEqual(expectedRadian, angle.Radians, TOLERANCE);
        }
예제 #6
0
파일: AngleTest.cs 프로젝트: daleghent/NINA
        public void StaticAtan2Test(double xRadians, double yRadians)
        {
            var xAngle = Angle.ByRadians(xRadians);
            var yAngle = Angle.ByRadians(yRadians);
            var angle  = Angle.Atan2(yAngle, xAngle);

            var rad            = Math.Atan2(yRadians, xRadians);
            var expectedDegree = Astrometry.ToDegree(rad);
            var expectedArcmin = Astrometry.DegreeToArcmin(expectedDegree);
            var expectedArcsec = Astrometry.DegreeToArcsec(expectedDegree);
            var expectedHours  = Astrometry.DegreesToHours(expectedDegree);

            Assert.AreEqual(expectedHours, angle.Hours, TOLERANCE);
            Assert.AreEqual(rad, angle.Radians, TOLERANCE);
            Assert.AreEqual(expectedDegree, angle.Degree, TOLERANCE);
            Assert.AreEqual(expectedArcmin, angle.ArcMinutes, TOLERANCE);
            Assert.AreEqual(expectedArcsec, angle.ArcSeconds, TOLERANCE);
        }
예제 #7
0
        public async Task <PlateSolveResult> Center(CaptureSequence seq, CenterSolveParameter parameter, IProgress <PlateSolveProgress> solveProgress, IProgress <ApplicationStatus> progress, CancellationToken ct)
        {
            if (parameter?.Coordinates == null)
            {
                throw new ArgumentException(nameof(CenterSolveParameter.Coordinates));
            }
            if (parameter?.Threshold <= 0)
            {
                throw new ArgumentException(nameof(CenterSolveParameter.Threshold));
            }

            var centered = false;
            PlateSolveResult result;
            Separation       offset = new Separation();

            do
            {
                result = await CaptureSolver.Solve(seq, parameter, solveProgress, progress, ct);

                if (result.Success == false)
                {
                    //Solving failed. Give up.
                    break;
                }

                var position = (telescopeMediator.GetCurrentPosition() - offset).Transform(result.Coordinates.Epoch);
                result.Separation = result.DetermineSeparation(position);

                Logger.Debug($"Centering Solver - Scope Position: {position}; Centering Coordinates: {parameter.Coordinates}; Solve Result: {result.Coordinates}; Separation {result.Separation}");

                solveProgress?.Report(new PlateSolveProgress()
                {
                    PlateSolveResult = result
                });

                if (Math.Abs(result.Separation.Distance.ArcMinutes) > parameter.Threshold)
                {
                    progress?.Report(new ApplicationStatus()
                    {
                        Status = Locale.Loc.Instance["LblPlateSolveNotInsideToleranceSyncing"]
                    });
                    if (parameter.NoSync || !await telescopeMediator.Sync(result.Coordinates))
                    {
                        offset = result.DetermineSeparation(position + offset);

                        Logger.Debug($"Sync failed - calculating offset instead to compensate.  Original: {position.Transform(result.Coordinates.Epoch)}; Solved: {result.Coordinates}; Offset: {offset}");
                        progress?.Report(new ApplicationStatus()
                        {
                            Status = Locale.Loc.Instance["LblPlateSolveSyncViaTargetOffset"]
                        });
                    }
                    else
                    {
                        var positionAfterSync = telescopeMediator.GetCurrentPosition().Transform(result.Coordinates.Epoch);

                        if (Astrometry.DegreeToArcsec(Math.Abs(positionAfterSync.RADegrees - result.Coordinates.RADegrees)) > 1 ||
                            Astrometry.DegreeToArcsec(Math.Abs(positionAfterSync.Dec - result.Coordinates.Dec)) > 1)
                        {
                            offset = result.DetermineSeparation(positionAfterSync);
                            Logger.Debug($"Sync failed silently - calculating offset instead to compensate.  Original: {positionAfterSync}; Solved: {result.Coordinates}; Offset: {offset}");
                        }
                        else
                        {
                            // Sync worked - reset offset
                            Logger.Debug("Synced sucessfully");
                            offset = new Separation();
                        }
                    }

                    Logger.Trace($"Slewing to target after sync. Target coordinates RA: {parameter.Coordinates.RAString} Dec: {parameter.Coordinates.DecString} Epoch: {parameter.Coordinates.Epoch}");
                    progress?.Report(new ApplicationStatus()
                    {
                        Status = Locale.Loc.Instance["LblPlateSolveNotInsideToleranceReslew"]
                    });

                    await telescopeMediator.SlewToCoordinatesAsync(parameter.Coordinates + offset);

                    progress?.Report(new ApplicationStatus()
                    {
                        Status = Locale.Loc.Instance["LblPlateSolveNotInsideToleranceRepeating"]
                    });
                }
                else
                {
                    centered = true;
                }
            } while (!centered);
            return(result);
        }
예제 #8
0
        protected override PlateSolveResult ReadResult(
            string outputFilePath,
            PlateSolveParameter parameter,
            PlateSolveImageProperties imageProperties)
        {
            var result = new PlateSolveResult()
            {
                Success = false
            };

            if (!File.Exists(outputFilePath))
            {
                Notification.ShowError("ASTAP - Plate solve failed. No output file found.");
                return(result);
            }

            var dict = File.ReadLines(outputFilePath)
                       .Where(line => !string.IsNullOrWhiteSpace(line))
                       .Select(line => line.Split(new char[] { '=' }, 2, 0))
                       .ToDictionary(parts => parts[0], parts => parts[1]);

            dict.TryGetValue("WARNING", out var warning);

            if (!dict.ContainsKey("PLTSOLVD") || dict["PLTSOLVD"] != "T")
            {
                dict.TryGetValue("ERROR", out var error);
                Notification.ShowError($"ASTAP - Plate solve failed.{Environment.NewLine}{warning}{Environment.NewLine}{error}");
                return(result);
            }

            if (!string.IsNullOrWhiteSpace(warning))
            {
                Notification.ShowWarning($"ASTAP - {warning}");
            }

            var wcs = new WorldCoordinateSystem(
                double.Parse(dict["CRVAL1"], CultureInfo.InvariantCulture),
                double.Parse(dict["CRVAL2"], CultureInfo.InvariantCulture),
                double.Parse(dict["CRPIX1"], CultureInfo.InvariantCulture),
                double.Parse(dict["CRPIX2"], CultureInfo.InvariantCulture),
                double.Parse(dict["CD1_1"], CultureInfo.InvariantCulture),
                double.Parse(dict["CD1_2"], CultureInfo.InvariantCulture),
                double.Parse(dict["CD2_1"], CultureInfo.InvariantCulture),
                double.Parse(dict["CD2_2"], CultureInfo.InvariantCulture)
                );

            result.Success     = true;
            result.Coordinates = new Coordinates(
                double.Parse(dict["CRVAL1"], CultureInfo.InvariantCulture),
                double.Parse(dict["CRVAL2"], CultureInfo.InvariantCulture),
                Epoch.J2000,
                Coordinates.RAType.Degrees
                );

            result.Orientation = double.Parse(dict["CROTA2"], CultureInfo.InvariantCulture);

            /*
             * CDELT1 and CDELT2 are obsolete.
             * To calculate pixel scale, we should add the squares of CD1_2 and CD2_2 and take the square root to get degrees.
             */
            if (dict.ContainsKey("CD1_2") && dict.ContainsKey("CD2_2"))
            {
                double.TryParse(dict["CD1_2"], NumberStyles.Any, CultureInfo.InvariantCulture, out double cr1y);
                double.TryParse(dict["CD2_2"], NumberStyles.Any, CultureInfo.InvariantCulture, out double cr2y);

                result.Pixscale = Astrometry.DegreeToArcsec(Math.Sqrt(Math.Pow(cr1y, 2) + Math.Pow(cr2y, 2)));
            }

            /* Due to the way N.I.N.A. writes FITS files, the orientation is mirrored on the x-axis */
            result.Orientation = wcs.Rotation - 180;
            result.Flipped     = !wcs.Flipped;

            return(result);
        }