예제 #1
0
        private async Task TransmitHeadingToNextWaypoint(string comment)
        {
            var nextWayPoint = _wayPoints.First();

            var wH = (int)Geospatial.BearingTo(_sender.Position.Coordinate,
                                               new Coordinate(nextWayPoint.Latitude, nextWayPoint.Longitude));

            var magneticHeading = Regex.Replace(Geospatial.TrueToMagnetic(_sender.Position, wH).ToString("000"),
                                                "\\d{1}", " $0");

            _lastInstruction = DateTime.Now;
            await SendMessage($"fly heading {magneticHeading} for {nextWayPoint.Name} {comment}");
        }
예제 #2
0
        public static async Task <string> Process(IRadioCall radioCall, string voice,
                                                  ConcurrentQueue <byte[]> responseQueue)
        {
            return(await Task.Run(() =>
            {
                try
                {
                    var airfield = Constants.Airfields.First(x => x.Name == radioCall.ReceiverName);
                    var approachRoute = new ApproachController(airfield).GetApproachRoute(radioCall.Sender.Position);

                    var initialTrueBearing = Geospatial.BearingTo(radioCall.Sender.Position.Coordinate,
                                                                  new Coordinate(approachRoute.First().Latitude, approachRoute.First().Longitude));

                    var initialMagneticBearing =
                        Regex.Replace(
                            Geospatial.TrueToMagnetic(radioCall.Sender.Position, initialTrueBearing).ToString("000"),
                            "\\d{1}", " $0");

                    var response =
                        $"fly heading {initialMagneticBearing}, descend and maintain 2,000, reduce speed 2 0 0 knots, for vectors to {approachRoute.Last().Name}, {approachRoute.First().Name}";

                    var currentPosition = new NavigationPoint
                    {
                        Name = "Current Position",
                        Latitude = radioCall.Sender.Position.Coordinate.Latitude,
                        Longitude = radioCall.Sender.Position.Coordinate.Longitude
                    };

                    approachRoute = approachRoute.Prepend(currentPosition).ToList();

                    new AtcProgressChecker(radioCall.Sender, airfield, voice, approachRoute, responseQueue)
                    .CalledInbound();

                    return response;
                }
                catch (InvalidOperationException)
                {
                    return "There are no ATC services currently available at this airfield.";
                }
                catch (NoActiveRunwaysFoundException ex)
                {
                    Logger.Error(ex, "No Active Runways found");
                    return "We could not find any active runways.";
                }
            }));
        }
예제 #3
0
        private async Task CheckInbound()
        {
            await PerformCheck(async() =>
            {
                Logger.Debug($"{_sender.Id} - {_sender.Callsign}: Inbound Progress Check");
                var nextWayPoint = _wayPoints.First();

                Logger.Debug(
                    $"{_sender.Id} is {nextWayPoint.DistanceTo(_sender.Position.Coordinate)} KM from {nextWayPoint.Name}");

                // THINK ABOUT: Change this fixed value to a relative ratio based on the distances?
                if (nextWayPoint.DistanceTo(_sender.Position.Coordinate) < 1)
                {
                    if (nextWayPoint.Name.Contains("Entry"))
                    {
                        await _atcState.FireAsync(Trigger.TurnBase);
                    }
                    else
                    {
                        await _atcState.FireAsync(Trigger.StartInbound);
                    }

                    return;
                }

                // No point with last minute instructions when we are sending them to initial soon anyway
                if (nextWayPoint.DistanceTo(_sender.Position.Coordinate) < 2.5)
                {
                    return;
                }

                if (_sender.Heading == null)
                {
                    Logger.Debug($"{_sender.Id} - {_sender.Callsign}: heading was null");
                    return;
                }

                Logger.Debug($"{_sender.Id} - {_sender.Callsign}: Time between two transmissions ok");

                var sH = (int)_sender.Heading;
                var wH = (int)Geospatial.BearingTo(_sender.Position.Coordinate,
                                                   new Coordinate(nextWayPoint.Latitude, nextWayPoint.Longitude));

                var headingDiff = Math.Min((wH - sH) < 0 ? wH - sH + 360 : wH - sH,
                                           (sH - wH) < 0 ? sH - wH + 360 : sH - wH);

                Logger.Debug(
                    $"{_sender.Id} - {_sender.Callsign}: Headings: Waypoint {wH}, Player {sH}, diff {headingDiff}");

                Logger.Debug(
                    $"{_sender.Id} - {_sender.Callsign}: {(DateTime.Now - _lastInstruction).TotalSeconds} since last transmission");
                if ((DateTime.Now - _lastInstruction).TotalMilliseconds < _transmissionInterval)
                {
                    Logger.Debug(
                        $"{_sender.Id} - {_sender.Callsign}: Time between two transmissions too low, returning");
                    return;
                }

                if (headingDiff <= 5)
                {
                    return;
                }

                var magneticHeading = Regex.Replace(Geospatial.TrueToMagnetic(_sender.Position, wH).ToString("000"),
                                                    "\\d{1}", " $0");
                _lastInstruction = DateTime.Now;
                await SendMessage($"fly heading {magneticHeading}");
            });
        }