예제 #1
0
        private TaxiInstructions GetTaxiInstructionsWhenMultipleRunways(TaxiPoint source, List <Runway> runways)
        {
            var tryGetPaths = _airfield.NavigationGraph.ShortestPathsDijkstra(_airfield.NavigationCostFunction, source);

            var cheapestPathCost = double.PositiveInfinity;
            IEnumerable <TaggedEdge <NavigationPoint, string> > cheapestPath = new List <TaggedEdge <NavigationPoint, string> >();
            Runway closestRunway = null;

            foreach (var runway in runways)
            {
                if (!tryGetPaths(runway, out var path))
                {
                    continue;
                }
                var taggedEdges = path.ToList();
                var pathCost    = PathCost(taggedEdges);
                if (!(pathCost < cheapestPathCost))
                {
                    continue;
                }
                closestRunway    = runway;
                cheapestPath     = taggedEdges;
                cheapestPathCost = pathCost;
            }
            return(CompileInstructions(closestRunway, cheapestPath));
        }
예제 #2
0
        private TaxiInstructions GetTaxiInstructionsWhenSingleRunway(TaxiPoint source, Runway target)
        {
            var tryGetPaths = _airfield.NavigationGraph.ShortestPathsDijkstra(_airfield.NavigationCostFunction, source);

            if (tryGetPaths(target, out var path))
            {
                return(CompileInstructions(target, path));
            }
            throw new TaxiPathNotFoundException($"No taxi path found from {source.Name} to {target.Name}");
        }
예제 #3
0
        private static TaxiInstructions CompileInstructions(TaxiPoint target, IEnumerable <TaggedEdge <TaxiPoint, string> > path)
        {
            var taggedEdges = path.ToList();

            var taxiInstructions = new TaxiInstructions()
            {
                DestinationName = target.Name,
                TaxiPoints      = taggedEdges.Select(edge => edge.Source).ToList(),
                Comments        = new List <string>()
            };

            // Include the final TaxiPoint
            taxiInstructions.TaxiPoints.Add(taggedEdges.Last().Target);
            foreach (var edge in taggedEdges)
            {
                taxiInstructions.TaxiwayNames.Add(edge.Tag);
            }

            taxiInstructions.TaxiwayNames = RemoveRepeating(taxiInstructions.TaxiwayNames);

            Logger.Debug(taxiInstructions);

            return(taxiInstructions);
        }
        private async Task CheckAsync()
        {
            try
            {
                Logger.Debug($"Peforming Taxi Progress check for {_sender.Id}");
                var previousId = _sender.Id;
                await GameQuerier.PopulatePilotData(_sender);

                // If the caller does not exist any more or the ID has been reused for a different object then cancel the check.
                if (_sender.Id == null || _sender.Id != previousId)
                {
                    _sender.Id = "DELETED";
                    Logger.Debug(
                        $"Stopping Taxi Progress Check. CallerId changed, New: {_sender.Id} , Old: {previousId}.");
                    Stop();
                    return;
                }

                var closestPoint = _taxiPoints.OrderBy(taxiPoint => taxiPoint.DistanceTo(_sender.Position.Coordinate))
                                   .First();

                // If the player is more than 5 miles from the closest TaxiPoint they they are long gone and should not longer
                // be monitored
                if (closestPoint.DistanceTo(_sender.Position.Coordinate) > 5)
                {
                    Stop();
                    return;
                }

                // If this is true then we don't need to say the same commands again etc.
                if (_currentTaxiPoint == closestPoint)
                {
                    return;
                }

                // We want to get rid of all the previous TaxiPoints in the list. We do this instead of just getting rid of the first in case
                // somehow the pilot manage to skip a TaxiPoint by going fast enough that they passed it before the check.
                var index = _taxiPoints.IndexOf(_currentTaxiPoint);

                if (index > 1)
                {
                    Logger.Trace($" {_sender.Id} skipped at least one taxi point");
                }

                for (var i = _taxiPoints.Count - 1; i >= 0; i--)
                {
                    if (i > index)
                    {
                        continue;
                    }
                    Logger.Trace($"Removing {_taxiPoints[i].Name} from route of {_sender.Id}");
                    _taxiPoints.RemoveAt(i);
                }

                _currentTaxiPoint = closestPoint;
                Logger.Debug($"New closest TaxiPoint to {_sender.Id} is {_currentTaxiPoint.Name}");

                if (_currentTaxiPoint is Runway)
                {
                    using (var activity = Constants.ActivitySource.StartActivity("TaxiProgressChecker.SendTaxiInstruction", ActivityKind.Consumer))
                    {
                        if (_taxiPoints.Count == 1)
                        {
                            Logger.Debug(
                                $"Stopping Taxi Progress Check. {_sender.Id} has reached the end of the taxi route at {_currentTaxiPoint.Name}");
                            activity?.AddTag("Response", "RunwayTakeOff");
                            await SendMessage($"Take-off {_currentTaxiPoint.Name} at your discretion");
                        }
                        else
                        {
                            activity?.AddTag("Response", "RunwayCrossing");
                            // If we have reached this bit in the code then the current taxi point is a runway that is not the terminus of the route
                            // so tell the player they are good to cross.
                            await SendMessage($"cross {_currentTaxiPoint.Name} at your discretion");
                        }
                    }
                }
                else if (_taxiPoints.Count == 1)
                {
                    Logger.Error(
                        $"{_currentTaxiPoint.Name} is the last point in the taxi path but is not a runway");
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "Error checking taxi progress");
            }
        }
예제 #5
0
        static void Main(string[] args)
        {
            var graph = new UndirectedGraph <TaxiPoint, TaggedEdge <TaxiPoint, string> >();

            // Krymsk Airfield
            TaxiPoint runwayFour = new TaxiPoint("Runway 4");
            TaxiPoint adJunction = new TaxiPoint("Alpha / Delta Junction");
            TaxiPoint acJunction = new TaxiPoint("Alpha / Charlie Junction");
            TaxiPoint bdJunction = new TaxiPoint("Bravo / Delta Junction");
            TaxiPoint padsFourteenThroughTwenty = new TaxiPoint("Pads 14 to 20");

            graph.AddVertex(runwayFour);
            graph.AddVertex(adJunction);
            graph.AddVertex(acJunction);
            graph.AddVertex(bdJunction);
            graph.AddVertex(padsFourteenThroughTwenty);

            TaggedEdge <TaxiPoint, string> runwayFourToAdJunction = new TaggedEdge <TaxiPoint, string>(runwayFour, adJunction, "Alpha");
            TaggedEdge <TaxiPoint, string> adJunctionToAcJunction = new TaggedEdge <TaxiPoint, string>(adJunction, acJunction, "Alpha");
            TaggedEdge <TaxiPoint, string> adJunctionToBdJunction = new TaggedEdge <TaxiPoint, string>(adJunction, bdJunction, "Delta");
            TaggedEdge <TaxiPoint, string> acJunctionToPadsFourteenThroughTwenty = new TaggedEdge <TaxiPoint, string>(acJunction, padsFourteenThroughTwenty, "Charlie");

            graph.AddEdge(runwayFourToAdJunction);
            graph.AddEdge(adJunctionToAcJunction);
            graph.AddEdge(adJunctionToBdJunction);
            graph.AddEdge(acJunctionToPadsFourteenThroughTwenty);

            Dictionary <TaggedEdge <TaxiPoint, string>, double> edgeCostDictionary = new Dictionary <TaggedEdge <TaxiPoint, string>, double>(graph.EdgeCount)
            {
                { runwayFourToAdJunction, 1 },
                { adJunctionToAcJunction, 1 },
                { adJunctionToBdJunction, 1 },
                { acJunctionToPadsFourteenThroughTwenty, 1 }
            };

            string dotGraph = graph.ToGraphviz(algorithm =>
            {
                // Custom init example
                algorithm.FormatVertex += (sender, vertexArgs) =>
                {
                    vertexArgs.VertexFormat.Label = $"{vertexArgs.Vertex.Name}";
                };
                algorithm.FormatEdge += (sender, edgeArgs) =>
                {
                    var label = new QuikGraph.Graphviz.Dot.GraphvizEdgeLabel
                    {
                        Value = $"Taxiway {edgeArgs.Edge.Tag} : Cost {edgeCostDictionary[edgeArgs.Edge]}"
                    };
                    edgeArgs.EdgeFormat.Label = label;
                };
            });

            Console.WriteLine("Graph Definition");
            Console.WriteLine("-------------------------------------");
            Console.WriteLine(dotGraph);
            Console.WriteLine("-------------------------------------");
            Console.WriteLine("Shortest Path Test");

            TaxiPoint root = padsFourteenThroughTwenty;

            Func <TaggedEdge <TaxiPoint, string>, double> edgeCost = AlgorithmExtensions.GetIndexer(edgeCostDictionary);

            TryFunc <TaxiPoint, IEnumerable <TaggedEdge <TaxiPoint, string> > > tryGetPaths = graph.ShortestPathsDijkstra(edgeCost, root);

            // Query path for given vertices
            TaxiPoint target = runwayFour;

            Console.WriteLine("Getting Path");

            if (tryGetPaths(target, out IEnumerable <TaggedEdge <TaxiPoint, string> > path))
            {
                List <string> taxiways = new List <string>();
                foreach (TaggedEdge <TaxiPoint, string> edge in path)
                {
                    taxiways.Add(edge.Tag);
                }

                Console.WriteLine("{0} to {1} via taxiways {2}", root.Name, target.Name, string.Join(", ", RemoveRepeating(taxiways)));
            }
            else
            {
                Console.WriteLine("Path was null");
            }

            Console.WriteLine("Press Enter to close");
            Console.ReadLine();
        }