示例#1
0
        //Read values from driver through methods
        private void CheckTelescopeStatus()
        {
            //if device present at all and its ID is set
            if (Enabled && DRIVER_NAME != "" && objTelescope != null)
            {
                try
                {
                    Connected_flag    = this.Connect;
                    curAzimuth        = this.Azimuth;
                    curAltitude       = this.Altitude;
                    curRightAscension = this.RightAscension;
                    curDeclination    = this.Declination;
                    curSiderealTime   = this.SiderealTime;

                    curPierSideStatus = this.PierSideStatus;

                    curAtPark   = this.AtPark;
                    curTracking = this.Tracking;

                    curSlewing = this.Slewing;
                }
                catch (Exception ex)
                {
                    Logging.AddLog("CheckTelescopeStatus error [" + ex.ToString() + "]", LogLevel.Important, Highlight.Error);
                }
            }
            else
            {
                //Print if somebody try to connect if device isn't presetn. Mostly for debug
                //Logging.AddLog("Telescope is not set. Couldn't set Park status", LogLevel.Debug, Highlight.Error);
            }
        }
示例#2
0
        public void DestinationSideOfPierTest()
        {
            Assert.IsTrue(_mgr.Connected);

            Vector currentPosition = GetTargetRaDec();

            _svc.MockRaDec        = currentPosition;
            _svc.MockSideOfPier   = PierSide.pierWest;
            _svc.MockIsWeakDriver = false;

            PierSide currentSOP = _mgr.GetTargetSideOfPier(currentPosition.X, currentPosition.Y);

            Assert.AreEqual <PierSide>(PierSide.pierWest, currentSOP);

            Vector targetPosition = currentPosition - new Vector(7.0, 0.0);

            if (targetPosition.X < 0)
            {
                targetPosition.X += 24;
            }
            _svc.MockSideOfPier = PierSide.pierEast;
            PierSide targetSOP = _mgr.GetTargetSideOfPier(targetPosition.X, targetPosition.Y);

            Assert.IsTrue(targetSOP == PierSide.pierEast);

            _svc.MockIsWeakDriver = true;
            targetSOP             = _mgr.GetTargetSideOfPier(targetPosition.X, targetPosition.Y);
            Assert.IsTrue(targetSOP == PierSide.pierEast);
        }
 public SlewInProgressMessage(bool isSlewInProgress, double rightAscension = double.NaN, double declination = double.NaN
                              , PierSide sideOfPier = PierSide.pierUnknown)
 {
     IsSlewInProgress = isSlewInProgress;
     RightAscension   = rightAscension;
     Declination      = declination;
     SideOfPier       = sideOfPier;
 }
示例#4
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);
 }
        private IRestRequest BuildSetSideOfPierRequest(PierSide sideOfPier)
        {
            var parameters = new Dictionary <string, object>
            {
                { TelescopeCommandParameters.SideOfPier, ((int)sideOfPier).ToString() }
            };

            return(RequestBuilder.BuildRestRequest(TelescopeCommand.SideOfPier, Method.PUT, parameters, GetClientTransactionId()));
        }
示例#6
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);
        }
示例#7
0
        public Form1()
        {
            XmlConfigurator.Configure();
            test1 = new MountCheck(1, "Conectar y luego Park 3.");
            test1.TimeOutSeconds = 50;
            test2 = new MountCheck(2, "DEC ClockWise");
            test2.TimeOutSeconds = 35;
            test3 = new MountCheck(3, "DEC CounterClockWise");
            test3.TimeOutSeconds = 70;
            test4 = new MountCheck(4, "Alt 86, Az 270");
            test4.TimeOutSeconds = 35;
            test5 = new MountCheck(5, "Check RA East Limit.");
            test5.TimeOutSeconds = 250;
            test6 = new MountCheck(6, "Alt 86, Az 90,Ra Home");
            test6.TimeOutSeconds = 80;
            test7 = new MountCheck(7, "Check RA West Limit.");
            test7.TimeOutSeconds = 250;

            logger.Info("Constructor Start.");
            raLimit         = false;
            raLimitLast     = false;
            tiltLimit       = false;
            tiltLimitLast   = false;
            this.udpClient  = new UdpClient();
            this.arduinoTcp = new ArduinoTcp(settings.ipAddress, (int)settings.port);
            InitializeComponent();

            stat         = null;
            pierFlips    = 0;
            pierSide     = PierSide.pierUnknown;
            pierSideLast = PierSide.pierUnknown;

            this.arduinoLimits.Open();
            this.timerReadSerial.Start();
            this.radioButtonDecHome.Checked = false;
            this.radioButtonRA_East.Checked = false;
            this.radioButtonRA_Home.Checked = false;
            this.radioButtonRA_West.Checked = false;

            //try
            //{
            //    this.telescopio = new Telescope(settings.TelescopeProgId);
            //}
            //catch (Exception)
            //{
            //    this.telescopio = null;
            //    logger.Error("Error al escoger telescopio ASCOM.");
            //}
            logger.Info("Constructor End.");
        }
        public PierSide DestinationSideOfPier(double rightAscension, double declination)
        {
            RightAscensionConverter raConverter  = new RightAscensionConverter((decimal)rightAscension);
            DeclinationConverter    decConverter = new DeclinationConverter((decimal)declination);

            LogActivityStart(ActivityMessageTypes.Other, " Get DestinationSideOfPier \r\n   RA {0}\r\n   Dec {1}:", raConverter, decConverter);
            CheckDevice();
            PierSide retval = Service.DestinationSideOfPier(rightAscension, declination);
            string   name   = GetPierSideName(retval);

            LogActivityEnd(ActivityMessageTypes.Other, "{0} {1}", name, Done);

            return(retval);
        }
示例#9
0
        public PierSide GetDecSideOfPier(double dec)
        {
            PierSide decSOP = PierSide.pierUnknown;

            dec = Math.Abs(dec - 180);
            if (dec <= 90.0)
            {
                decSOP = PierSide.pierEast;
            }
            else
            {
                decSOP = PierSide.pierWest;
            }
            return(decSOP);
        }
        //public double RightAscensionRate
        //{
        //    get
        //    {
        //        double rightAscensionRate = 0.0;
        //        tl.LogMessage("RightAscensionRate", "Get - " + rightAscensionRate.ToString());
        //        return rightAscensionRate;
        //    }
        //    set
        //    {
        //        tl.LogMessage("RightAscensionRate Set", "Not implemented");
        //        throw new ASCOM.PropertyNotImplementedException("RightAscensionRate", true);
        //    }
        //}

        //public void SetPark()
        //{
        //    tl.LogMessage("SetPark", "Not implemented");
        //    throw new ASCOM.MethodNotImplementedException("SetPark");
        //}

        private void UpdateSideOfPier()
        {
            if (Slewing || AtHome)
            {
                UpdatingSideOfPier = false;
                return;
            }

            double HourAngle = astroUtilities.ConditionHA(SiderealTime - RightAscension);

            bool NearMeridian = (HourAngle < -11 || HourAngle > 11) || (HourAngle > -1 && HourAngle < 1);

            if (!NearMeridian) // SideOfPier is constrained by mount design (no need to send :pS# command)
            {
                _SideOfPier        = (HourAngle > 0) ? PierSide.pierEast : PierSide.pierWest;
                UpdatingSideOfPier = false;
                return;
            }

            //Command: “:pS#”
            //Response: “0” East, “1” West.
            var SideOfPierTransaction = new ZEQ25BooleanTransaction(":pS#")
            {
                Timeout = TimeSpan.FromSeconds(2)
            };

            Task.Run(() => transactionProcessor.CommitTransaction(SideOfPierTransaction));
            SideOfPierTransaction.WaitForCompletionOrTimeout();
            String response = SideOfPierTransaction.Response.ToString();

            log.Info("Update SideOfPier (Response): {0}", SideOfPierTransaction.Response);

            // pierEast is returned when the mount is observing at an hour angle between -12.0 and  -6.0
            // pierWest is returned when the mount is observing at an hour angle between  -6.0 and   0.0
            // pierEast is returned when the mount is observing at an hour angle between   0.0 and  +6.0
            // pierWest is returned when the mount is observing at an hour angle between  +6.0 and +12.0

            // "Through the pole"
            if (HourAngle < -6 || HourAngle > 6) // between -12.0 and -6.0 or between + 6.0 and + 12.0
            {
                _SideOfPier = SideOfPierTransaction.Value ? PierSide.pierEast : PierSide.pierWest;
            }
            else // between -6.0 and 0.0 or between 0.0 and + 6.0 (Normal pointing state) - 1 = West, 0 = East
            {
                _SideOfPier = SideOfPierTransaction.Value ? PierSide.pierWest : PierSide.pierEast;
            }
            UpdatingSideOfPier = false;
        }
示例#11
0
        /// <summary>
        /// Wrapper to reset telescope driver
        /// Later system would reinitiate it itself
        /// </summary>
        public void Reset()
        {
            Connected_flag = false;

            curAzimuth        = -1;
            curAltitude       = -100;
            curRightAscension = -100;
            curDeclination    = -100;
            curSiderealTime   = -100;
            curPierSideStatus = PierSide.pierUnknown;

            curAtPark   = false;
            curTracking = false;

            objTelescope = null;
        }
示例#12
0
        public void MeridianFlipTest()
        {
            // Unpark the scope and start tracking.

            _svc.MockAtPark        = false;
            _svc.MockTracking      = true;
            _svc.MockSideOfPier    = PierSide.pierWest;
            _mgr.Status.SideOfPier = PierSide.pierWest;

            Thread.Sleep(5000);               // Give the telescope manager time to do a status update.

            Assert.IsFalse(_mgr.AtPark);
            Assert.IsTrue(_mgr.Tracking);
            Assert.IsTrue(_mgr.Capabilities.CanSetPierSide);
            Assert.IsTrue(_mgr.Status.SideOfPier == PierSide.pierWest);

            // Verify that both the Manager and the Service have the same side-of-pier and that
            // it is not Unknown.

            PierSide sop = _mgr.SideOfPier;

            Assert.IsTrue(sop != PierSide.pierUnknown);
            Assert.IsTrue(sop == _svc.SideOfPier);

            // Do the flip.

            _mgr.StartMeridianFlip();

            // Wait for the flip.

            Thread.Sleep(6000);

            while (_mgr.Slewing)
            {
                Thread.Sleep(500);
            }

            // Make sure that we are done and on the expected side of the mount.

            Assert.IsFalse(_mgr.Slewing);

            // Figure out which side we should end up on after the flip.

            PierSide targetSop = sop == PierSide.pierEast ? PierSide.pierWest : PierSide.pierEast;

            Assert.AreEqual(targetSop, _mgr.SideOfPier);
        }
示例#13
0
        /// <summary>
        /// Returns the pointing side of Pier as required by ASCOM
        /// </summary>
        public PierSide GetPointingSideOfPier(bool swapSideOfPier)
        {
            PierSide pointingSOP = PierSide.pierUnknown;

            if (ObservedAxes != null)
            {
                if (ObservedAxes[1] == 0.0)
                {
                    // Impossible to tell so return unknown
                    return(pointingSOP);
                }
                if (ObservedAxes[1] > 180.0) //  (ObservedAxes[1] <= 90 || ObservedAxes[1] >= 270.0)
                {
                    if (swapSideOfPier)
                    {
                        pointingSOP = PierSide.pierEast;
                    }
                    else
                    {
                        pointingSOP = PierSide.pierWest;
                    }
                }
                else
                {
                    if (swapSideOfPier)
                    {
                        pointingSOP = PierSide.pierWest;
                    }
                    else
                    {
                        pointingSOP = PierSide.pierEast;
                    }
                }
                if (Hemisphere == HemisphereOption.Southern)
                {
                    if (pointingSOP == PierSide.pierWest)
                    {
                        pointingSOP = PierSide.pierWest;
                    }
                    else
                    {
                        pointingSOP = PierSide.pierEast;
                    }
                }
            }
            return(pointingSOP);
        }
示例#14
0
 public ActionResult <PierSideResponse> Get(int ClientID, int ClientTransactionID, double RightAscension, double Declination)
 {
     try
     {
         PierSide result = Program.Simulator.DestinationSideOfPier(RightAscension, RightAscension);
         Program.TraceLogger.LogMessage(methodName + " Get", result.ToString());
         return(new PierSideResponse(ClientTransactionID, ClientID, result));
     }
     catch (Exception ex)
     {
         Program.TraceLogger.LogMessage(methodName + " Get", string.Format("Exception: {0}", ex.ToString()));
         PierSideResponse response = new PierSideResponse(ClientTransactionID, ClientID, 0, 0);
         response.ErrorMessage = ex.Message;
         response.ErrorNumber  = ex.HResult - Program.ASCOM_ERROR_NUMBER_OFFSET;
         return(response);
     }
 }
示例#15
0
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            try {
                PierSide pierSide = (PierSide)value;
                switch (pierSide)
                {
                case PierSide.pierEast:
                    return(Locale.Loc.Instance["LblEast"]);

                case PierSide.pierWest:
                    return(Locale.Loc.Instance["LblWest"]);

                default:
                    return(string.Empty);
                }
            } catch (Exception ex) {
                Logger.Error(ex, $"Failed to convert {value} to PierSide");
                return(string.Empty);
            }
        }
示例#16
0
        public bool GetSideOfPier(out PierSide pierSide)
        {
            bool success = false;

            pierSide = PierSide.pierUnknown;
            if (RequestReply(":pS#", out string pierSideReply))
            {
                switch (pierSideReply)
                {
                case "East#":
                    pierSide = PierSide.pierEast;
                    success  = true;
                    break;

                case "West#":
                    pierSide = PierSide.pierWest;
                    success  = true;
                    break;
                }
            }
            return(success);
        }
示例#17
0
        private bool CalculateCounterWeightUp(PierSide pierSide, double hourAngle)
        {
            //	The CW state is determined by looking at two things:  pier side and hour angle (HA = LST – RA).
            //		Pier Side = West;                    0 > HA > -12              CW Down
            //		Pier Side = East;                    0 < HA < +12              CW Down
            //
            //		Pier Side = East;                    0 > HA > -12              CW UP
            //		Pier Side = West;                    0 < HA < +12              CW UP

            bool retval = false;

            if (pierSide == PierSide.pierEast && -12 < hourAngle && hourAngle < 0)
            {
                retval = true;
            }
            else if (pierSide == PierSide.pierWest && 0 < hourAngle && hourAngle < 12)
            {
                retval = true;
            }

            return(retval);
        }
示例#18
0
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string retval = null;

            PierSide sop = (PierSide)value;

            switch (sop)
            {
            case PierSide.pierEast:
                retval = "East";
                break;

            case PierSide.pierWest:
                retval = "West";
                break;

            case PierSide.pierUnknown:
                retval = "Unknown";
                break;
            }

            return(retval);
        }
示例#19
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);
                }
            }
        }
示例#20
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());
 }
示例#21
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();
            }
        }
示例#22
0
        /// <summary>
        /// Refreshes the NCP and current positions if more than 500ms have elapsed since the last refresh.
        /// </summary>
        private void RefreshCurrentPosition()
        {
            DateTime     now          = DateTime.Now;
            bool         axisHasMoved = false;
            double       tolerance;
            AxisPosition axisPosition; //= _previousAxisPosition;

            lock (Controller)
            {
                _AxisState   = Controller.MCGetAxesStates();
                axisPosition = Controller.MCGetAxisPositions();
                tolerance    = Controller.AngularResolutionDegrees;
            }
#if DEBUG
            //string raStatus = Convert.ToString(axesStatus[RA_AXIS], 2);
            //string decStatus = Convert.ToString(axesStatus[DEC_AXIS], 2); ;
            //System.Diagnostics.Debug.WriteLine($"\nAxis states - RA: {raStatus}, Dec : {decStatus}\n");
            //AxisState raStatus = _AxisState[RA_AXIS];
            //AxisState decStatus = _AxisState[DEC_AXIS];
            //System.Diagnostics.Debug.WriteLine($"\nRA : Slewing-{raStatus.Slewing}, SlewingTo-{raStatus.SlewingTo}, Forward-{!raStatus.MeshedForReverse}, FullStop-{raStatus.FullStop}, Tracking-{raStatus.Tracking}");
            //System.Diagnostics.Debug.WriteLine($"Dec: Slewing-{decStatus.Slewing}, SlewingTo-{decStatus.SlewingTo}, Forward-{!decStatus.MeshedForReverse}, FullStop-{decStatus.FullStop}, Tracking-{decStatus.Tracking}");
#endif
            if (!axisPosition.Equals(_previousAxisPosition, tolerance))
            //if (!_AxisState[RA_AXIS].FullStop || !_AxisState[DEC_AXIS].FullStop)
            {
                // One or the other axis is moving
                axisHasMoved = true;
                if (_previousPointingSOP == PierSide.pierUnknown)
                {
                    // First move away from home (NCP/SCP) position.
                    if (_TargetPosition != null)
                    {
                        System.Diagnostics.Debug.WriteLine("Initialising SOP from goto target.");
                        System.Diagnostics.Debug.WriteLine($"Target Axes: {_TargetPosition.ObservedAxes.RAAxis.Value}/{_TargetPosition.ObservedAxes.DecAxis.Value}\t{_TargetPosition.ObservedAxes.DecFlipped}\tRA/Dec: {_TargetPosition.Equatorial.RightAscension}/{_TargetPosition.Equatorial.Declination}\t{_TargetPosition.PointingSideOfPier}");
                        axisPosition.DecFlipped = _TargetPosition.ObservedAxes.DecFlipped;
                        _previousPointingSOP    = _TargetPosition.PointingSideOfPier;
                    }
                }
                else
                {
                    // Keep the axis position the same
                    axisPosition.DecFlipped = _previousAxisPosition.DecFlipped;
                }
            }
            else
            {
                // Check if parking.
                if (Settings.ParkStatus == ParkStatus.Parking)
                {
                    // Update the parked axis position decflipped setting if it isn't set.
                    _ParkedAxisPosition.DecFlipped = _previousAxisPosition.DecFlipped;
                    if (axisPosition.Equals(_ParkedAxisPosition, tolerance))
                    {
                        LogMessage("Command", "Park - complete");
                        Settings.ParkStatus = ParkStatus.Parked;
                        SaveSettings();
                    }
                    else
                    {
                        //if (_NeedSlowToStopStep)
                        //{
                        // Need to keep going
                        Controller.MCAxisSlewTo(_ParkedAxisPosition, Hemisphere);
                        //   _NeedSlowToStopStep = false;
                        //}
                    }
                }

                axisPosition.DecFlipped = _previousAxisPosition.DecFlipped;
            }

            // Update current position
            _CurrentPosition.MoveRADec(axisPosition, _AscomToolsCurrentPosition, now);

            if (!_decFlippedConfirmed && _CurrentPosition.PointingSideOfPier != PierSide.pierUnknown)
            {
                double ha = AstroConvert.RangeHA(SiderealTime - _CurrentPosition.Equatorial.RightAscension.Value);
                if (_CurrentPosition.PointingSideOfPier == PierSide.pierWest)
                {
                    if (ha >= 0)
                    {
                        // need to flip the DEC axis as it is reporting the wrong RA
                        axisPosition.DecFlipped = !axisPosition.DecFlipped;
                        _CurrentPosition.MoveRADec(axisPosition, _AscomToolsCurrentPosition, now);
                    }
                }
                else
                {
                    if (ha < 0)
                    {
                        // need to flip the DEC axis as it is reporting the wrong RA
                        axisPosition.DecFlipped = !axisPosition.DecFlipped;
                        _CurrentPosition.MoveRADec(axisPosition, _AscomToolsCurrentPosition, now);
                    }
                }
                _decFlippedConfirmed = true;
            }

            //// Just check that we have the DecFlipped setting correct
            //if (!_decFlippedConfirmed && _IsSlewing)
            //{
            //   double deltaRa = _TargetPosition.Equatorial.RightAscension - _CurrentPosition.Equatorial.RightAscension;
            //   if (_previousDeltaRa.HasValue)
            //   {
            //      if (deltaRa > _previousDeltaRa.Value)
            //      {
            //         // Going in the wrong direction so flip the Dec axis
            //         axisPosition.DecFlipped = !axisPosition.DecFlipped;
            //         _CurrentPosition.MoveRADec(axisPosition, _AscomToolsCurrentPosition, now);
            //      }
            //      _decFlippedConfirmed = true;
            //   }
            //   else {
            //      // Get it on the next cycle
            //      _previousDeltaRa = deltaRa;
            //   }
            //}

            if (_previousPointingSOP != PierSide.pierUnknown)
            {
                // See if pointing has moved across the meridian
                if (_CurrentPosition.PointingSideOfPier != _previousPointingSOP)
                {
                    System.Diagnostics.Debug.WriteLine("** Crossing the meridian **");
                    // Pointing has moved across the meridian so toggle the DecFlipped value;
                    axisPosition.DecFlipped = !_previousAxisPosition.DecFlipped;
                    _CurrentPosition.MoveRADec(axisPosition, _AscomToolsCurrentPosition, now);
                }
            }


            if (Settings.ParkStatus == ParkStatus.Parking)
            {
                System.Diagnostics.Debug.WriteLine($"Parking to: {_ParkedAxisPosition.RAAxis.Value}/{_ParkedAxisPosition.RAAxis.Value}\t{_ParkedAxisPosition.DecFlipped}");
            }

            if (_TargetPosition != null)
            {
                System.Diagnostics.Debug.WriteLine($"Target Axes: {_TargetPosition.ObservedAxes.RAAxis.Value}/{_TargetPosition.ObservedAxes.DecAxis.Value}\t{_TargetPosition.ObservedAxes.DecFlipped}\tRA/Dec: {_TargetPosition.Equatorial.RightAscension}/{_TargetPosition.Equatorial.Declination}\t{_TargetPosition.PointingSideOfPier}");
            }
            if (Settings.ParkStatus == ParkStatus.Parked)
            {
                System.Diagnostics.Debug.WriteLine("Parked");
            }
            else
            {
                // System.Diagnostics.Debug.WriteLine($"Current Axes: {axisPosition.RAAxis.Value}/{axisPosition.DecAxis.Value}\t{axisPosition.DecFlipped}\tRA/Dec: {_CurrentPosition.Equatorial.RightAscension}/{_CurrentPosition.Equatorial.Declination}\t{_CurrentPosition.PointingSideOfPier}\n");
            }

            _previousAxisPosition = axisPosition;
            // See if we can sort out the initial SideOfPier
            if (_previousPointingSOP == PierSide.pierUnknown)
            {
                // Only initialise the previous pointing SOP if we know for certain what it should be
                if (axisHasMoved && (_IsSlewing || _IsMoveAxisSlewing))
                {
                    // Remember the current pointing side of the pier.
                    // Until the SOP has been determined from a SLEW or GOTO it should not be updated.
                    _previousPointingSOP = _CurrentPosition.PointingSideOfPier;
                }
            }
            else
            {
                _previousPointingSOP = _CurrentPosition.PointingSideOfPier;
            }

            // If the axis has stopped moving there are some bit to clear up
            if (_wasMoving && !axisHasMoved)
            {
                // See if we need to refine a goto.
                if (_RefineGoto)
                {
                    _RefineGoto = false;
                    System.Diagnostics.Debug.WriteLine("Refining GOTO");
                    SlewToEquatorialCoordinate(TargetRightAscension, TargetDeclination);
                }
                else
                {
                    if (Settings.ParkStatus == ParkStatus.Unparked)
                    {
                        // Check if slew finished
                        if (_IsSlewing)
                        {
                            _IsSlewing = false;
                            // Announce("Slew complete.");
                        }
                        if (_IsMoveAxisSlewing)
                        {
                            _IsMoveAxisSlewing = false;
                        }
                        if (!_IsMoveAxisSlewing && !_IsSlewing)
                        {
                            if (TrackingState != TrackingStatus.Off)
                            {
                                System.Diagnostics.Debug.WriteLine("Restarting tracking");
                                LogMessage("Command", "Restarting tracking {0}", TrackingState);
                                StartTracking();
                            }
                        }
                    }
                }
            }

            _wasMoving = axisHasMoved;
        }
示例#23
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);
                }
            }
        }
示例#24
0
        /// <summary>
        /// Lee el estado del telescopio desde los drivers de ASCOM.
        /// </summary>
        private void ProcesaTelescopio()
        {
            StringBuilder mensaje;

            mensaje = new StringBuilder();
            Boolean conectado;

            conectado = false;
            try
            {
                if (this.telescopio != null)
                {
                    try
                    {
                        conectado = telescopio.Connected;
                    }
                    catch (NullReferenceException nref)
                    {
                        logger.Debug(nref.Message);
                        conectado = false;
                    }
                }
            }
            catch (DriverAccessCOMException e)
            {
                conectado = false;
                logger.Debug(e.Message);
            }
            if (conectado)
            {
                mensaje.Append("Conectado,");
                double ra, dec;
                try
                {
                    ra  = telescopio.RightAscension;
                    dec = telescopio.Declination;
                }
                catch (DriverAccessCOMException e)
                {
                    ra = dec = 0;
                    logger.Debug(e.Message);
                }


                slewing = false;
                try
                {
                    slewing = telescopio.Slewing;
                }
                catch (DriverAccessCOMException e)
                {
                    slewing = false;
                    logger.Debug(e.Message);
                }

                if ((this.checkBoxInfrared.Checked) && (slewing != lastSlewing))
                {
                    this.InfraredControl(slewing);
                }

                if (slewing)
                {
                    mensaje.Append("Slewing,");
                }
                else
                {
                    mensaje.Append("Stationary,");
                }

                #region PierSide
                mensaje.Append("PierSide=");
                this.pierSide = telescopio.SideOfPier;
                //if (pierFlips == 0)
                //{
                //    this.pierSideLast = pierSide;
                //}
                String strPierSide;
                strPierSide = "_undef";
                switch (this.pierSide)
                {
                case (PierSide.pierEast):
                    strPierSide = "East";
                    break;

                case PierSide.pierUnknown:
                    strPierSide = "Unknown";
                    break;

                case PierSide.pierWest:
                    strPierSide = "West";
                    break;
                }
                mensaje.Append(strPierSide);
                // SI:
                // 1) Si los ultimos dos estados estan bien determinados.
                // 2) Ambos estados son diferentes
                // ENtonces:
                // Se ha detectado un  Trasito de la montura, o un GEM Flip.

                if ((pierSide != PierSide.pierUnknown) &&     //1)
                    (pierSideLast != PierSide.pierUnknown) && //1)
                    (pierSide != pierSideLast))
                {
                    pierFlips++;
                    logger.Info("#Flips=" + pierFlips + ". Actual pierside=" + strPierSide);
                }
                mensaje.Append("#Flips=");
                mensaje.Append(pierFlips);

                pierSideLast = pierSide;
                #endregion
                //mensaje.Append(" RA=");
                //mensaje.Append(String.Format("{0:0.00}", ra));
                //mensaje.Append(" DEC=");
                //mensaje.Append(String.Format("{0:0.00}", dec));
                lastSlewing = slewing;
            }
            else
            {
                mensaje.Append("Telescope ProdID=");
                mensaje.Append(settings.TelescopeProgId);
                mensaje.Append(" ;; Desconectado");
            }
            this.labelTelescope.Text = mensaje.ToString();
            //this.timerTelescopio.Start();
        }
示例#25
0
 private AlignmentPoint GetNearestMountPoint(AxisPosition axisPosition, PierSide pierSide)
 {
     return(AlignmentPoints
            .Where(p => p.PierSide == pierSide)
            .OrderBy(d => d.MountAxes.IncludedAngleTo(axisPosition)).FirstOrDefault());
 }
 /// <inheritdoc/>
 public async Task SetSideOfPierAsync(PierSide sideOfPier) => await ExecuteRequestAsync(BuildSetSideOfPierRequest, sideOfPier);
示例#27
0
        public void ShouldFlipTest(double timeToFlipMinutes, double exposureTimeMinutes, double minutesAfterMeridian, double pauseBeforeMeridian, bool useSideOfPier, bool shouldFlip, PierSide pierSide = PierSide.pierUnknown)
        {
            meridianFlipSettingsMock.SetupGet(m => m.Enabled).Returns(true);
            meridianFlipSettingsMock.SetupGet(m => m.MinutesAfterMeridian).Returns(minutesAfterMeridian);
            meridianFlipSettingsMock.SetupGet(m => m.PauseTimeBeforeMeridian).Returns(pauseBeforeMeridian);
            meridianFlipSettingsMock.SetupGet(m => m.Recenter).Returns(false);
            meridianFlipSettingsMock.SetupGet(m => m.SettleTime).Returns(0);
            meridianFlipSettingsMock.SetupGet(m => m.UseSideOfPier).Returns(useSideOfPier);

            var telescopeInfo = new TelescopeInfo()
            {
                TimeToMeridianFlip = TimeSpan.FromMinutes(timeToFlipMinutes).TotalHours,
                SideOfPier         = pierSide,
                Connected          = true
            };

            var exposureTime = TimeSpan.FromMinutes(exposureTimeMinutes).TotalSeconds;

            var sut = MeridianFlipVM.ShouldFlip(profileServiceMock.Object, exposureTime, telescopeInfo);

            sut.Should().Be(shouldFlip);
        }
示例#28
0
 public PierSideResponse(int clientTransactionID, int transactionID, PierSide side)
 {
     base.ServerTransactionID = transactionID;
     base.ClientTransactionID = clientTransactionID;
     PierSide = side;
 }
 /// <inheritdoc/>
 public void SetSideOfPier(PierSide sideOfPier) => ExecuteRequest(BuildSetSideOfPierRequest, sideOfPier);