Example #1
0
        private void LoadAlignmentPoints()
        {
            var dir = Path.GetDirectoryName(_configFile);

            if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
            if (File.Exists(_configFile))
            {
                AlignmentPoints.Clear();
                using (var file = File.OpenText(_configFile))
                {
                    var serializer = new JsonSerializer();
                    var loaded     = (AlignmentPointCollection)serializer.Deserialize(file, typeof(AlignmentPointCollection));
                    if (loaded != null)
                    {
                        foreach (var alignmentPoint in loaded)
                        {
                            AlignmentPoints.Add(alignmentPoint);
                        }
                    }
                }
            }
            ReportAlignmentPoints();
        }
Example #2
0
        private void AddAlignmentPoint(double[] mountAltAz, double[] observedAltAz, AxisPosition mountAxes, AxisPosition observedAxes, PierSide pierSide, DateTime syncTime)
        {
            lock (_accessLock)
            {
                if (AlignmentPoints.Count > 2 && ProximityLimit > 0.0)
                {
                    // Remove any existing alignment points that are too close to the new one.
                    var nearPoints = AlignmentPoints
                                     .Where(p => p.MountAxes.IncludedAngleTo(mountAxes) <= ProximityLimit).ToList();
                    foreach (AlignmentPoint deletePt in nearPoints)
                    {
                        AlignmentPoints.Remove(deletePt);
                    }
                }

                CarteseanCoordinate mountXy    = AltAzToCartesean(mountAltAz);
                CarteseanCoordinate observedXy = AltAzToCartesean(observedAltAz);
                AlignmentPoints.Add(new AlignmentPoint(observedAltAz, mountAxes, observedAxes, mountXy, observedXy, pierSide, syncTime));

                _currentChecksum = int.MinValue;    // Reset checksum so that offsets are recalculated

                OneStarAdjustment[0] = observedAxes[0] - mountAxes[0];
                OneStarAdjustment[1] = observedAxes[1] - mountAxes[1];
                SaveAlignmentPoints();
            }
        }
Example #3
0
 private AlignmentPoint[] GetNearestObservedPoints(AxisPosition axisPosition, PierSide pierSide, int numberOfPoints, out int checkSum)
 {
     AlignmentPoint[] points = AlignmentPoints
                               .Where(p => p.PierSide == pierSide && p.ObservedAxes.IncludedAngleTo(axisPosition) <= NearbyLimit)
                               .OrderBy(d => d.ObservedAxes.IncludedAngleTo(axisPosition)).Take(numberOfPoints).ToArray();
     checkSum = GetChecksum(points.Select(p => p.Id).ToArray());
     return(points);
 }
Example #4
0
        private AlignmentPoint GetNearestObservedPoint(AxisPosition axisPosition, PierSide pierSide, out int checkSum)
        {
            AlignmentPoint alignmentPoint = AlignmentPoints
                                            .Where(p => p.PierSide == pierSide)
                                            .OrderBy(d => d.ObservedAxes.IncludedAngleTo(axisPosition)).FirstOrDefault();

            checkSum = alignmentPoint != null?GetChecksum(alignmentPoint.Id) : int.MinValue;

            return(alignmentPoint);
        }
Example #5
0
 public void ClearAlignmentPoints()
 {
     try
     {
         AlignmentPoints.Clear();
         SaveAlignmentPoints();
     }
     catch (Exception ex)
     {
         LogException(ex, true);
     }
 }
Example #6
0
 private void AlignmentPoints_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
 {
     if (e.Action == NotifyCollectionChangedAction.Add)
     {
         SelectedAlignmentPoint = AlignmentPoints[e.NewStartingIndex + e.NewItems.Count - 1];
     }
     else
     {
         if (!AlignmentPoints.Contains(SelectedAlignmentPoint))
         {
             SelectedAlignmentPoint = AlignmentPoints.FirstOrDefault();
         }
     }
     ClearAllPointsCommand.RaiseCanExecuteChanged();
     DeleteSelectedPointCommand.RaiseCanExecuteChanged();
 }
Example #7
0
        public bool RemoveAlignmentPoint(AlignmentPoint pointToDelete)
        {
            try
            {
                bool result = AlignmentPoints.Remove(pointToDelete);
                if (result)
                {
                    SaveAlignmentPoints();
                }

                return(result);
            }
            catch (Exception ex)
            {
                LogException(ex, true);
                return(false);
            }
        }
Example #8
0
        /// <summary>
        /// Gets the observed axis positions for a given mount axis position.
        /// </summary>
        /// <param name="mountAxes">Mount Ra and Dec axis positions</param>
        /// <param name="pierSide">The pier side to use 0 = East, 1 = West, 2 = Unknown</param>
        /// <returns></returns>
        public double[] GetObservedAxes(double[] mountAxes, int pierSide)
        {
            if (!IsAlignmentOn || !AlignmentPoints.Any())
            {
                return(mountAxes);                                            // Fast exit as alignment modeling is switched off or there are no points.
            }
            lock (_accessLock)
            {
                try
                {
                    AxisPosition mAxes = new AxisPosition(mountAxes);
                    if (mAxes.IncludedAngleTo(_homePosition) < ProximityLimit)
                    {
                        return(mountAxes); // Fast exist if we are going home.
                    }
                    RaiseNotification(NotificationType.Information, MethodBase.GetCurrentMethod().Name,
                                      $"GetObservedAxes for {mountAxes[0]}/{mountAxes[1]}");
                    PierSide pSide = (PierSide)pierSide;
                    WriteLastAccessTime();
                    Matrix offsets = Matrix.CreateInstance(1, 2);
                    if (AlignmentPoints.Count == 1)
                    {
                        offsets[0, 0] = AlignmentPoints[0].ObservedAxes[0] - AlignmentPoints[0].MountAxes[0];
                        offsets[0, 1] = AlignmentPoints[0].ObservedAxes[1] - AlignmentPoints[0].MountAxes[1];
                        RaiseNotification(NotificationType.Data, MethodBase.GetCurrentMethod().Name,
                                          $"Single alignment point selected {AlignmentPoints[0].Id:D3}, Mount axes: {AlignmentPoints[0].MountAxes.RaAxis}/{AlignmentPoints[0].MountAxes.RaAxis}, Observed axes: {AlignmentPoints[0].ObservedAxes.RaAxis}/{AlignmentPoints[0].ObservedAxes.RaAxis}");
                    }
                    else
                    {
                        AlignmentPoint[] alignmentPoints = GetNearestMountPoints(mAxes, pSide, SampleSize);
                        int rows = alignmentPoints.Length;

                        if (rows > 2)
                        {
                            // Build features and values from registered points
                            Matrix features = Matrix.CreateInstance(rows, 3);
                            Matrix values   = Matrix.CreateInstance(rows, 2);

                            _stringBuilder.Clear();
                            _stringBuilder.Append("Points chosen are");
                            for (int i = 0; i < rows; i++)
                            {
                                var pt = alignmentPoints[i];
                                _stringBuilder.Append($" ({pt.Id:D3})");
                                features[i, 0] = 1f;
                                features[i, 1] = pt.MountAxes[0] * pt.MountAxes[0];
                                features[i, 2] = pt.MountAxes[1] * pt.MountAxes[1];
                                values[i, 0]   = Range.RangePlusOrMinus180(pt.ObservedAxes[0] - pt.MountAxes[0]);
                                values[i, 1]   = Range.RangePlusOrMinus180(pt.ObservedAxes[1] - pt.MountAxes[1]);
                            }

                            _stringBuilder.AppendLine(".");



                            // Solve the normal equation to get theta
                            Matrix theta = SolveNormalEquation(features, values);

                            // Calculate the difference for the incoming points
                            Matrix target = Matrix.CreateInstance(1, 3);
                            target[0, 0] = 1f;
                            target[0, 1] = mAxes[0] * mAxes[0];
                            target[0, 2] = mAxes[1] * mAxes[1];

                            offsets = target * theta;


                            _stringBuilder.AppendLine("Features");
                            _stringBuilder.AppendLine(features.ToString());
                            _stringBuilder.AppendLine("Values");
                            _stringBuilder.AppendLine(values.ToString());
                            _stringBuilder.AppendLine("Theta");
                            _stringBuilder.AppendLine(theta.ToString());
                            _stringBuilder.AppendLine("Target");
                            _stringBuilder.AppendLine(target.ToString());
                            _stringBuilder.AppendLine("Offsets");
                            _stringBuilder.AppendLine(offsets.ToString());
                            RaiseNotification(NotificationType.Data, MethodBase.GetCurrentMethod().Name, _stringBuilder.ToString());
                            _stringBuilder.Clear();
                        }
                        else if (rows > 0)
                        {
                            // Just use the nearest point of the two.
                            offsets[0, 0] = alignmentPoints[0].ObservedAxes[0] - alignmentPoints[0].MountAxes[0];
                            offsets[0, 1] = alignmentPoints[0].ObservedAxes[1] - alignmentPoints[0].MountAxes[1];
                            RaiseNotification(NotificationType.Data, MethodBase.GetCurrentMethod().Name,
                                              $"Using nearest point of two {alignmentPoints[0].Id:D3}, Mount axes: {alignmentPoints[0].MountAxes.RaAxis}/{alignmentPoints[0].MountAxes.RaAxis}, Observed axes: {alignmentPoints[0].ObservedAxes.RaAxis}/{alignmentPoints[0].ObservedAxes.RaAxis}");
                        }
                        // Otherwise default to using no correcting offset
                    }

                    var observedAxes = new[]
                    {
                        mountAxes[0] + offsets[0, 0],
                        mountAxes[1] + offsets[0, 1]
                    };
                    RaiseNotification(NotificationType.Data, MethodBase.GetCurrentMethod().Name,
                                      $"Correction -> Observer = {offsets[0, 0]}/{offsets[0, 1]}");
                    RaiseNotification(NotificationType.Information, MethodBase.GetCurrentMethod().Name,
                                      $"Mount axes: {mountAxes[0]}/{mountAxes[1]} -> Observed axes: {observedAxes[0]}/{observedAxes[1]}");

                    return(observedAxes);
                }
                catch (Exception ex)
                {
                    LogException(ex, true);
                    return(mountAxes);
                }
            }
        }
Example #9
0
 private AlignmentPoint[] GetNearestMountPoints(AxisPosition axisPosition, PierSide pierSide, int numberOfPoints)
 {
     return(AlignmentPoints
            .Where(p => p.PierSide == pierSide && p.MountAxes.IncludedAngleTo(axisPosition) <= NearbyLimit)
            .OrderBy(d => d.MountAxes.IncludedAngleTo(axisPosition)).Take(numberOfPoints).ToArray());
 }
Example #10
0
        /// <summary>
        /// Gets the mount axis positions for a given observed axis position.
        /// </summary>
        /// <param name="observedAxes">Observed Ra and Dec axis positions</param>
        /// <param name="pierSide">The pier side to use 0 = East, 1 = West, 2 = Unknown</param>
        /// <returns></returns>
        public double[] GetMountAxes(double[] observedAxes, int pierSide)
        {
            if (!IsAlignmentOn || !AlignmentPoints.Any())
            {
                return(observedAxes);                                          // Fast exit as alignment modeling is switched off or there are no points.
            }
            lock (_accessLock)
            {
                try
                {
                    bool         postLogMessages = false;
                    AxisPosition sAxes           = new AxisPosition(observedAxes);
                    if (sAxes.IncludedAngleTo(_homePosition) < ProximityLimit)
                    {
                        return(observedAxes); // Fast exit if we are going home.
                    }
                    PierSide pSide = (PierSide)pierSide;
                    WriteLastAccessTime();
                    Matrix offsets = Matrix.CreateInstance(1, 2);
                    int    checksum;

                    if (AlignmentPoints.Count == 1)
                    {
                        checksum = GetChecksum(AlignmentPoints[0].Id);
                        if (checksum == _currentChecksum)
                        {
                            // Checksum hasn't changed so use the last offsets
                            offsets = _lastOffsets;
                        }
                        else
                        {
                            RaiseNotification(NotificationType.Information, MethodBase.GetCurrentMethod().Name,
                                              $"GetMountAxes for {observedAxes[0]}/{observedAxes[1]}");
                            ClearSelectedPoints();
                            offsets[0, 0] = AlignmentPoints[0].MountAxes[0] - AlignmentPoints[0].ObservedAxes[0];
                            offsets[0, 1] = AlignmentPoints[0].MountAxes[1] - AlignmentPoints[0].ObservedAxes[1];
                            AlignmentPoints[0].Selected = true;
                            _selectedPoints.Add(AlignmentPoints[0]);
                            // Cache the offsets and checksum
                            _lastOffsets     = offsets;
                            _currentChecksum = checksum;
                            RaiseNotification(NotificationType.Data, MethodBase.GetCurrentMethod().Name,
                                              $"Single alignment point selected {AlignmentPoints[0].Id:D3}, Mount axes: {AlignmentPoints[0].MountAxes.RaAxis}/{AlignmentPoints[0].MountAxes.RaAxis}, Observed axes: {AlignmentPoints[0].ObservedAxes.RaAxis}/{AlignmentPoints[0].ObservedAxes.RaAxis}");
                            postLogMessages = true;
                        }
                    }
                    else
                    {
                        // Get the nearest points and their corresponding checksum value
                        AlignmentPoint[] alignmentPoints =
                            GetNearestObservedPoints(sAxes, pSide, SampleSize, out checksum);
                        if (checksum == _currentChecksum)
                        {
                            // Checksum hasn't changed to use the last offsets
                            offsets = _lastOffsets;
                        }
                        else
                        {
                            int rows = alignmentPoints.Length;
                            if (rows > 2)
                            {
                                RaiseNotification(NotificationType.Information, MethodBase.GetCurrentMethod().Name,
                                                  $"GetMountAxes for {observedAxes[0]}/{observedAxes[1]}");
                                ClearSelectedPoints();
                                // Build features and values from registered points
                                Matrix features = Matrix.CreateInstance(rows, 3);
                                Matrix values   = Matrix.CreateInstance(rows, 2);
                                _stringBuilder.Clear();
                                _stringBuilder.Append("Points chosen are");
                                for (int i = 0; i < rows; i++)
                                {
                                    var pt = alignmentPoints[i];
                                    _stringBuilder.Append($" ({pt.Id:D3})");
                                    features[i, 0] = 1f;
                                    features[i, 1] = pt.ObservedAxes[0] * pt.ObservedAxes[0];
                                    features[i, 2] = pt.ObservedAxes[1] * pt.ObservedAxes[1];
                                    values[i, 0]   = Range.RangePlusOrMinus180(pt.MountAxes[0] - pt.ObservedAxes[0]);
                                    values[i, 1]   = Range.RangePlusOrMinus180(pt.MountAxes[1] - pt.ObservedAxes[1]);
                                    pt.Selected    = true;
                                    _selectedPoints.Add(pt);
                                }

                                _stringBuilder.AppendLine(".");

                                // Solve the normal equation to get theta
                                Matrix theta = SolveNormalEquation(features, values);

                                // Calculate the difference for the incoming points
                                Matrix target = Matrix.CreateInstance(1, 3);
                                target[0, 0] = 1f;
                                target[0, 1] = sAxes[0] * sAxes[0];
                                target[0, 2] = sAxes[1] * sAxes[1];

                                offsets = target * theta;


                                _stringBuilder.AppendLine("Features");
                                _stringBuilder.AppendLine(features.ToString());
                                _stringBuilder.AppendLine("Values");
                                _stringBuilder.AppendLine(values.ToString());
                                _stringBuilder.AppendLine("Theta");
                                _stringBuilder.AppendLine(theta.ToString());
                                _stringBuilder.AppendLine("Target");
                                _stringBuilder.AppendLine(target.ToString());
                                _stringBuilder.AppendLine("Offsets");
                                _stringBuilder.AppendLine(offsets.ToString());
                                RaiseNotification(NotificationType.Data, MethodBase.GetCurrentMethod().Name, _stringBuilder.ToString());
                                _stringBuilder.Clear();

                                // Cache the offsets and the checksum
                                _lastOffsets     = offsets;
                                _currentChecksum = checksum;
                                postLogMessages  = true;
                            }
                            else if (rows > 0)
                            {
                                checksum = GetChecksum(AlignmentPoints[0].Id);
                                if (checksum == _currentChecksum)
                                {
                                    // Checksum hasn't changed so use the last offsets
                                    offsets = _lastOffsets;
                                }
                                else
                                {
                                    RaiseNotification(NotificationType.Information, MethodBase.GetCurrentMethod().Name,
                                                      $"GetMountAxes for {observedAxes[0]}/{observedAxes[1]}");

                                    ClearSelectedPoints();
                                    // Use the nearest point of the two.
                                    offsets[0, 0] =
                                        alignmentPoints[0].MountAxes[0] - alignmentPoints[0].ObservedAxes[0];
                                    offsets[0, 1] =
                                        alignmentPoints[0].MountAxes[1] - alignmentPoints[0].ObservedAxes[1];
                                    alignmentPoints[0].Selected = true;
                                    _selectedPoints.Add(alignmentPoints[0]);
                                    // Cache the offsets and checksum
                                    _lastOffsets     = offsets;
                                    _currentChecksum = checksum;
                                    postLogMessages  = true;
                                    RaiseNotification(NotificationType.Data, MethodBase.GetCurrentMethod().Name,
                                                      $"Using nearest point of two {alignmentPoints[0].Id:D3}, Mount axes: {alignmentPoints[0].MountAxes.RaAxis}/{alignmentPoints[0].MountAxes.RaAxis}, Observed axes: {alignmentPoints[0].ObservedAxes.RaAxis}/{alignmentPoints[0].ObservedAxes.RaAxis}");
                                }
                            }
                            else
                            {
                                if (_currentChecksum != int.MinValue)
                                {
                                    _currentChecksum = int.MinValue;
                                    RaiseNotification(NotificationType.Warning, MethodBase.GetCurrentMethod().Name,
                                                      $"No alignment points selected, Mount axes: {alignmentPoints[0].MountAxes.RaAxis}/{alignmentPoints[0].MountAxes.RaAxis}, Observed axes: {alignmentPoints[0].ObservedAxes.RaAxis}/{alignmentPoints[0].ObservedAxes.RaAxis}");
                                }
                            }
                        }

                        // Otherwise default to using zero offset
                    }

                    var mountAxes = new[]
                    {
                        observedAxes[0] + offsets[0, 0],
                        observedAxes[1] + offsets[0, 1]
                    };
                    if (postLogMessages)
                    {
                        RaiseNotification(NotificationType.Data, MethodBase.GetCurrentMethod().Name,
                                          $"Correction -> Mount = {offsets[0, 0]}/{offsets[0, 1]}");
                        RaiseNotification(NotificationType.Information, MethodBase.GetCurrentMethod().Name,
                                          $"Observed axes: {observedAxes[0]}/{observedAxes[1]} -> Mount axes: {mountAxes[0]}/{mountAxes[1]}");
                    }

                    return(mountAxes);
                }
                catch (Exception ex)
                {
                    LogException(ex);
                    return(observedAxes);
                }
            }
        }
Example #11
0
 private AlignmentPoint GetNearestMountPoint(AxisPosition axisPosition, PierSide pierSide)
 {
     return(AlignmentPoints
            .Where(p => p.PierSide == pierSide)
            .OrderBy(d => d.MountAxes.IncludedAngleTo(axisPosition)).FirstOrDefault());
 }