Example #1
0
 /// <inheritdoc />
 protected bool Equals(SatelliteVisibilityPeriod other)
 {
     return(Satellite.Equals(other.Satellite) &&
            Start.Equals(other.Start) &&
            End.Equals(other.End) &&
            MaxElevation.Equals(other.MaxElevation) &&
            MaxElevationTime.Equals(other.MaxElevationTime) &&
            ReferencePosition.Equals(other.ReferencePosition));
 }
Example #2
0
        /// <summary>
        ///     Creates a list of all of the predicted observations within the specified time period for this GroundStation.
        /// </summary>
        /// <param name="satellite">The satellite to observe</param>
        /// <param name="start">The time to start observing</param>
        /// <param name="end">The time to end observing</param>
        /// <param name="deltaTime">The time step for the prediction simulation</param>
        /// <param name="minElevation">The minimum elevation. Default is Angle.Zero.</param>
        /// <param name="clipToStartTime">Whether to clip the start time of the first satellite visibility period to start, if applicable. Default is true</param>
        /// <param name="clipToEndTime">Whether to clip the end time of the last satellite visibility period to end, if applicable. Default is false</param>
        /// <param name="resolution">The number of second decimal places to calculate for the start and end times. Cannot be greater than 7 (i.e. greater than tick resolution). Default is 3.</param>
        /// <returns>A list of observations where an AOS is seen at or after the start parameter</returns>
        /// <exception cref="ArgumentException">Thrown if start is greater than or equal to end, deltaTime is non-positive, resolution is not in range 0-7, or minElevation is greater than 90°</exception>
        public List <SatelliteVisibilityPeriod> Observe(
            Satellite satellite,
            DateTime start, DateTime end,
            TimeSpan deltaTime,
            Angle minElevation   = default(Angle), // default is Angle.Zero
            bool clipToStartTime = true,           // default is true as it is assumed typical use case will be for future propagation, not searching into the past
            bool clipToEndTime   = false,          // default is false as it is assumed typical use case will be to capture entire future pass
            int resolution       = 3)
        {
            // check input constraints
            if (deltaTime.TotalSeconds <= 0)
            {
                throw new ArgumentException("deltaTime must be positive", "deltaTime");
            }
            start = start.ToStrictUtc();
            end   = end.ToStrictUtc();
            if (start >= end)
            {
                throw new ArgumentException("start time must be less than end time", "start");
            }
            if (deltaTime <= TimeSpan.Zero)
            {
                throw new ArgumentException("deltaTime must be greater than zero", "deltaTime");
            }
            if (resolution < 0)
            {
                throw new ArgumentException("resolution must be non-negative", "resolution");
            }
            if (resolution > 7)
            {
                throw new ArgumentException("resolution must be no more than 7 decimal places (no more than tick resolution)", "resolution");
            }
            if (minElevation != null && minElevation.Degrees > 90)
            {
                throw new ArgumentException("minElevation cannot be greater than 90°", "minElevation");
            }

            start = start.Round(deltaTime);
            var clippedEnd = clipToEndTime ? (DateTime?)end : null;

            var obs = new List <SatelliteVisibilityPeriod>();

            DateTime aosTime;
            var      t = start;

            do
            {
                // find the AOS Time of the next pass
                aosTime = FindNextBelowToAboveCrossingPoint(satellite, t, end, deltaTime, minElevation, resolution);
                if (aosTime > end)
                {
                    break;
                }                             // if aosTime is greater than end, we're done
                t = aosTime + deltaTime;
                // find the LOS time and max elevation for the next pass
                DateTime losTime;
                DateTime maxElTime;
                if (clippedEnd.HasValue && t > clippedEnd.Value)
                {
                    losTime   = clippedEnd.Value;
                    maxElTime = clippedEnd.Value;
                }
                else
                {
                    var tu = FindNextAboveToBelowCrossingPoint(satellite, t, deltaTime, minElevation, resolution, clippedEnd);
                    losTime   = tu.CrossingPointTime;
                    maxElTime = tu.MaxElevationTime;
                }

                var before = maxElTime - deltaTime;
                if (clipToStartTime) // ensure before is clipped for max elevation search
                {
                    before = start > before ? start : before;
                }
                var after = maxElTime + deltaTime;
                if (clipToEndTime) // ensure after is clipped for max elevation search
                {
                    after = end < after ? end : after;
                }

                // add the visibility period for the pass
                var refinedMaxElResult = FindMaxElevation(satellite, before, maxElTime, after, resolution);
                var maxEl = refinedMaxElResult.Item1;
                maxElTime = refinedMaxElResult.Item2;
                obs.Add(new SatelliteVisibilityPeriod(satellite, aosTime, losTime, maxEl, maxElTime, Location));

                t = losTime + deltaTime;
            } while (t <= end);

            // if clipToStartTime is false and the start time has been clipped, walk back in time until previous AOS crossing point has been found
            if (!clipToStartTime && obs.Count > 0 && obs[0].Start == start)
            {
                var first              = obs[0];
                var tu                 = FindNextAboveToBelowCrossingPoint(satellite, first.Start, deltaTime.Negate(), minElevation, resolution);
                var maxElTime          = first.MaxElevation > tu.MaxElevation ? first.MaxElevationTime : tu.MaxElevationTime;
                var refinedMaxElResult = FindMaxElevation(satellite, maxElTime - deltaTime, maxElTime,
                                                          maxElTime + deltaTime, resolution);
                var maxEl = refinedMaxElResult.Item1;
                maxElTime = refinedMaxElResult.Item2;
                obs[0]    = new SatelliteVisibilityPeriod(satellite, tu.CrossingPointTime, first.End, maxEl, maxElTime, first.ReferencePosition);
            }

            return(obs);
        }
 /// <inheritdoc />
 protected bool Equals(SatelliteVisibilityPeriod other)
 {
     return(Satellite.Equals(other.Satellite) && Start.Equals(other.Start) && End.Equals(other.End) &&
            MaxElevation.Equals(other.MaxElevation) && StartAzimuth.Equals(other.StartAzimuth) &&
            EndAzimuth.Equals(other.EndAzimuth));
 }