예제 #1
0
    /// <summary>
    /// Apply an agent command to the character
    /// </summary>
    /// <returns>An observation after the action has been applied</returns>
    public Observation ProcessCommand(Command c, int gameTick, NavMeshContainer nav)
    {
        if (gameTick % 199 == 0)
        {
            _Character.SwitchCircleDirection();
        }

        switch (c.cmd)
        {
        case AgentCommandType.DONOTHING:
            break;

        case AgentCommandType.MOVETOWARD:
            AgentCommand <Tuple <Vector3, bool> > move = c as AgentCommand <Tuple <Vector3, bool> >;
            MoveToward(move.arg.object1, move.arg.object2);
            break;

        case AgentCommandType.INTERACT:
            AgentCommand interact     = c as AgentCommand;
            string       interactWith = interact.targetId;
            GameObject.Find(interactWith).GetComponent <Sensor>().Trigger();
            break;
        }

        observation.Observe(_Character, gameTick, nav, c.cmd);
        return(observation);
    }
예제 #2
0
        public override void Update()
        {
            base.Update();
            if (_behaviour == null)
            {
                return;
            }

            if (Agent.CurrentCommand != null && !Agent.CurrentCommand.Executable())
            {
                Interrupt();
            }

            AgentCommand newCommand = NextCommand();

            if (Agent.CurrentCommand == null || Agent.CurrentCommand.IsFinished() ||
                (Agent.CurrentCommand != null && newCommand.Priority > Agent.CurrentCommand.Priority + AgentConstants.PriorityShiftThreshold))
            {
                Agent.CurrentCommand = newCommand;
                Agent.CurrentAction  = null;
            }

            if (Agent.CurrentAction == null && Agent.CurrentCommand != null)
            {
                Agent.CurrentAction       = Agent.CurrentCommand.Action;
                Agent.CurrentActionTarget = Agent.CurrentCommand.Target;
            }
        }
예제 #3
0
        public void TestAgentMoveBentLine()
        {
            string levelString = @"
++++++++++++
+ +     G  +
+0+++++++  +
+          +
++++++++++++";

            List <AgentCommand> commands = new List <AgentCommand>()
            {
                AgentCommand.CreateMove(Direction.S),
                AgentCommand.CreateMove(Direction.E),
                AgentCommand.CreateMove(Direction.E),
                AgentCommand.CreateMove(Direction.E),
                AgentCommand.CreateMove(Direction.E),
                AgentCommand.CreateMove(Direction.E),
                AgentCommand.CreateMove(Direction.E),
                AgentCommand.CreateMove(Direction.E),
                AgentCommand.CreateMove(Direction.E),
                AgentCommand.CreateMove(Direction.N),
                AgentCommand.CreateMove(Direction.N),
                AgentCommand.CreateMove(Direction.W),
            };

            VerifyMoveAgentToGoalCreator(levelString, commands);
        }
예제 #4
0
        public void TestAgentCommandConstructorShouldWork()
        {
            AgentCommand command = new AgentCommand(_action1, new TangibleDefault(), 10);

            Assert.AreEqual(_action1, command.Action);
            Assert.AreEqual(10, command.Priority);
        }
예제 #5
0
        public void TestAgentToPullPullBent()
        {
            string levelString = @"
++++++++++++
++++0+++++++
++++ +++++++
++++ +++++++
+B       GF+
++++++++++++";

            List <AgentCommand> commands = new List <AgentCommand>()
            {
                AgentCommand.CreateMove(Direction.S),
                AgentCommand.CreateMove(Direction.S),
                AgentCommand.CreateMove(Direction.S),
                AgentCommand.CreateMove(Direction.W),
                AgentCommand.CreateMove(Direction.W),
                AgentCommand.CreatePull(Direction.E, Direction.W),
                AgentCommand.CreatePull(Direction.E, Direction.W),
                AgentCommand.CreatePull(Direction.E, Direction.W),
                AgentCommand.CreatePull(Direction.E, Direction.W),
                AgentCommand.CreatePull(Direction.E, Direction.W),
                AgentCommand.CreatePull(Direction.E, Direction.W),
                AgentCommand.CreatePull(Direction.E, Direction.W),
                AgentCommand.CreatePull(Direction.E, Direction.W),
            };

            VerifyMoveBoxToGoalCreator(levelString, commands);
        }
        public void TriggerThreadProfile()
        {
            var threadProfileArguments = new Dictionary <string, object>();

            threadProfileArguments["profile_id"]    = -1;
            threadProfileArguments["sample_period"] = 0.1F; //Agent enforces minimums
            threadProfileArguments["duration"]      = 120;  //Agent enforces minimums

            var threadProfileDetails = new CommandDetails("start_profiler", threadProfileArguments);
            var threadProfileCommand = new AgentCommand(-1, threadProfileDetails);

            _queuedCommands.Add(threadProfileCommand);
        }
예제 #7
0
        public AgentCommand CheckMessage()
        {
            AgentCommand command = AgentCommand.NoCommand;

            if (Messages.Count > 0)
            {
                AgentMessage msg = ReadMessage();
                if (msg.From == "Agency" && msg.Text == $"{AgentCommand.Stop}")
                {
                    command = AgentCommand.Stop;
                }
            }
            return(command);
        }
예제 #8
0
        public AgentCommand requestAgentCommand()
        {
            Dictionary <string, string> queryParams = new Dictionary <string, string>();

            queryParams.Add("client_ip", getLocalIPAddress());

            string urlPath = PcbAgent.buildUriForApiRequest(PcbAgent.REQUEST_AGENT_COMMAND);

            string result = HttpSender.requestNormal(urlPath, "GET", queryParams);

            Console.WriteLine("[requestAgentCommand] requestAgentCommand result:{0}", result);

            AgentCommand agentCmd = MsgConverter.unpack <AgentCommand>(result);

            return(agentCmd);
        }
        public void TriggerCustomInstrumentationEditorAgentCommand()
        {
            var configObj = new Dictionary <string, object>
            {
                ["config"] = _liveInstrumentation
            };

            var liveInstrumentationAgentCommandArguments = new Dictionary <string, object>
            {
                ["instrumentation"] = configObj
            };

            var liveInstrumentationAgentCommandDetails = new CommandDetails("instrumentation_update", liveInstrumentationAgentCommandArguments);
            var liveInstrumentationAgentCommand        = new AgentCommand(-1, liveInstrumentationAgentCommandDetails);

            _queuedCommands.Add(liveInstrumentationAgentCommand);
        }
예제 #10
0
        public void TestAgentToPushPushUTurn()
        {
            string levelString = @"
++++++
+  0 +
+ BFG+
++++++";

            List <AgentCommand> commands = new List <AgentCommand>()
            {
                AgentCommand.CreateMove(Direction.W),
                AgentCommand.CreatePush(Direction.S, Direction.E),
                AgentCommand.CreatePush(Direction.E, Direction.E),
            };

            VerifyMoveBoxToGoalCreator(levelString, commands);
        }
예제 #11
0
        public void Test_requestAgentCommand()
        {
            AgentCommand agentCmd = PcbAgent.Instance.requestAgentCommand();

            Assert.AreNotEqual <AgentCommand>(null, agentCmd);

            Console.WriteLine("AgentCommand cmd:{0}", agentCmd.cmd);

            foreach (GameCommand gameCmd in agentCmd.gameCommands)
            {
                Console.WriteLine("GameCommand gsn:{0}, exefile:{1}", gameCmd.gsn, gameCmd.exeFile);

                foreach (InstallPath path in gameCmd.expectedPaths)
                {
                    Console.WriteLine("InstallPath gsn:{0}, path:{1}", path.gsn, path.path);
                }
            }
        }
예제 #12
0
        public void TestPushPullTurnLast()
        {
            string levelString = @"
++++++++++
+0B    GF+
+++++++ ++
++++++++++";

            List <AgentCommand> commands = new List <AgentCommand>()
            {
                AgentCommand.CreatePush(Direction.E, Direction.E),
                AgentCommand.CreatePush(Direction.E, Direction.E),
                AgentCommand.CreatePush(Direction.E, Direction.E),
                AgentCommand.CreatePush(Direction.E, Direction.E),
                AgentCommand.CreatePush(Direction.E, Direction.E),
                AgentCommand.CreatePush(Direction.E, Direction.S),
                AgentCommand.CreatePull(Direction.E, Direction.S),
            };

            VerifyMoveBoxToGoalCreator(levelString, commands);
        }
예제 #13
0
        public void TestPullPush()
        {
            string levelString = @"
++++++++++
+B0    FG+
+++++ ++++
++++++++++";

            List <AgentCommand> commands = new List <AgentCommand>()
            {
                AgentCommand.CreatePull(Direction.E, Direction.W),
                AgentCommand.CreatePull(Direction.E, Direction.W),
                AgentCommand.CreatePull(Direction.E, Direction.W),
                AgentCommand.CreatePull(Direction.S, Direction.W),
                AgentCommand.CreatePush(Direction.N, Direction.E),
                AgentCommand.CreatePush(Direction.E, Direction.E),
                AgentCommand.CreatePush(Direction.E, Direction.E),
            };

            VerifyMoveBoxToGoalCreator(levelString, commands);
        }
예제 #14
0
        public static void Main(string[] args)
        {
            #if DEBUG
            if (args.Any(a => string.Equals(a, "--debug", StringComparison.Ordinal)))
            {
                args = args.Where(a => !string.Equals(a, "--debug", StringComparison.Ordinal)).ToArray();
                Console.WriteLine($"Waiting for debugger. Process ID: {Process.GetCurrentProcess().Id}");
                Console.WriteLine("Press ENTER to continue");
                Console.ReadLine();
            }
            #endif

            var app = new CommandLineApplication();
            app.Description = "Crank's Revenge";
            app.HelpOption("-h|--help");

            LocalCommand.Register(app);
            AgentCommand.Register(app);
            WorkerCommand.Register(app);
            ServerCommand.Register(app);

            app.Command("help", cmd =>
            {
                var commandArgument = cmd.Argument("<COMMAND>", "The command to get help for.");

                cmd.OnExecute(() =>
                {
                    app.ShowHelp(commandArgument.Value);
                    return(0);
                });
            });

            app.OnExecute(() =>
            {
                app.ShowHelp();
                return(0);
            });

            app.Execute(args);
        }
예제 #15
0
        public void TestAgentMoveStraightPath()
        {
            string levelString = @"
++++++++++++
+          +
+0       G +
+          +
++++++++++++";

            List <AgentCommand> commands = new List <AgentCommand>()
            {
                AgentCommand.CreateMove(Direction.E),
                AgentCommand.CreateMove(Direction.E),
                AgentCommand.CreateMove(Direction.E),
                AgentCommand.CreateMove(Direction.E),
                AgentCommand.CreateMove(Direction.E),
                AgentCommand.CreateMove(Direction.E),
                AgentCommand.CreateMove(Direction.E),
                AgentCommand.CreateMove(Direction.E),
            };

            VerifyMoveAgentToGoalCreator(levelString, commands);
        }
예제 #16
0
        //핵심 mission들 수행 test
        public string executeMissions(bool isForce)
        {
            //10초 ~ 1분 사이에 실행됨 실행
            Random random = new Random();

            Thread.Sleep(random.Next(20, DELAY_TIME_SEC) * 1000);

            if (!isForce && checkGamePatchPass())
            {
                return("PASS");
            }

            //request Agent Command
            AgentCommand agentCmd = requestAgentCommand();

            PcbGamePatch pcbGamePatch = new PcbGamePatch();

            pcbGamePatch.pcbGames = new List <PcbGame>();
            pcbGamePatch.version  = PcbAgent.AGENT_VERSION;

            //GameCommand 처리
            foreach (GameCommand gameCmd in agentCmd.gameCommands)
            {
                PcbGame pcbGame = executeGameCommand(gameCmd);
                if (pcbGame != null)
                {
                    pcbGamePatch.pcbGames.Add(pcbGame);
                }
            }

            //gamepatch 정보 전송
            String result = sendPcbGamePatchToMaster(pcbGamePatch);

            Debug.WriteLine("[executeMissions] sendPcbGamePatchToMaster result:" + result);
            return(result);
        }
예제 #17
0
        public async Task UpdateAgent(string agentId, AgentCommand command)
        {
            _logger.LogInformation($"Updating agent {agentId}");
            string agentJson = await _blobStoreService.GetText($"agents/{agentId}.json").ConfigureAwait(false);

            if (string.IsNullOrWhiteSpace(agentJson))
            {
                throw new ArgumentException($"Unknown agent: {agentId}");
            }

            var agent = JsonSerializer.Deserialize <MapAgent>(agentJson);

            string pathJson = await _blobStoreService.GetText(BuildPathPath(agentId), throwIfNotFound : false).ConfigureAwait(false);

            var oldPath = string.IsNullOrWhiteSpace(pathJson) ? new MapAgentPath() : JsonSerializer.Deserialize <MapAgentPath>(pathJson);

            var    newPath    = new MapAgentPath();
            long   pathUnixMs = GeoMath.UnixMs();
            long   pathMs     = 0;
            double pathMeters = 0;

            // Keep all points that are in the future - and one point in the past so we can interpolate the line segment
            List <GeoCoord> visitedPoints = new List <GeoCoord>();
            long            msPrev        = -1;

            for (int i = 0; i < oldPath.PointAbsTimestampMs.Count; ++i)
            {
                bool pointIsInTheFuture     = oldPath.PointAbsTimestampMs[i] >= pathUnixMs;
                bool nextPointIsInTheFuture = i < oldPath.PointAbsTimestampMs.Count - 1 && oldPath.PointAbsTimestampMs[i + 1] >= pathUnixMs;
                bool keepPoint = pointIsInTheFuture || nextPointIsInTheFuture;
                if (keepPoint)
                {
                    pathUnixMs = oldPath.PointAbsTimestampMs[i];
                    newPath.PointAbsTimestampMs.Add(pathUnixMs);
                    newPath.Points.Add(oldPath.Points[i]);
                    long msCurrent = oldPath.PointAbsTimestampMs[i];
                    if (msPrev != -1)
                    {
                        long segmentMs = msCurrent - msPrev;
                        pathMs += segmentMs;
                    }
                    msPrev = msCurrent;
                }
                else
                {
                    visitedPoints.Add(oldPath.Points[i]);
                }
            }

            // Make sure all visited lines are drawn by adding the points that are cut off.
            if (newPath.Points.Count > 1)
            {
                visitedPoints.Add(newPath.Points[0]);
                visitedPoints.Add(newPath.Points[1]);
            }

            await _mapCoverage.UpdateCoverage(visitedPoints).ConfigureAwait(false);

            {
                // If stuck, clear newPath and add a single point at or near a valid location. Then run update once from Cmd. A new valid path should now be written.
                //newPath.Points.Clear();
                //newPath.Points.Add(new GeoCoord(6.598364, 50.078052));
                //newPath.PointAbsTimestampMs.Clear();
                //newPath.PointAbsTimestampMs.Add(GeoMath.UnixMs());
            }

            if (newPath.Points.Count == 0)
            {
                // Path is out of date, nothing to keep. Reuse latest known position.
                int oldCount = oldPath.Points.Count;
                newPath.Points.Clear();
                newPath.PointAbsTimestampMs.Clear();
                newPath.Points.Add(oldPath.Points[oldCount - 1]);
                newPath.Points.Add(oldPath.Points[oldCount - 1]);
                newPath.PointAbsTimestampMs.Add(GeoMath.UnixMs());
            }

            // Start path here
            var startPoint = newPath.Points.Last();
            var startNode  = await _worldGraph.GetNearbyNode(startPoint).ConfigureAwait(false);

            List <GeoCoord> deadEndDebugSegments        = new List <GeoCoord>();
            List <GeoCoord> possibleWayoutDebugSegments = new List <GeoCoord>();

            double             prevBearing = double.MaxValue;
            List <WayTileNode> conn        = null;
            WayTileNode        prevNode    = null;
            WayTileNode        node        = startNode;
            WayTileNode        nextNode    = null;

            while (true)
            {
                conn = await _worldGraph.GetNodeConnections(node).ConfigureAwait(false);

                var options = conn.Select(x => new Option {
                    Node = x
                }).ToList();

                // Don't go back if we can go forward
                if (options.Count > 1)
                {
                    options = options.Where(x => x.Node != prevNode).ToList();
                }

                foreach (var option in options)
                {
                    var(deadEndFound, unexploredNodeFound, visitedNodesFound, unvisitedNodesFound, totalVisitCount, exploredSegments) = await _graphPeek.Peek(node, option.Node).ConfigureAwait(false);

                    double bearing = GeoMath.CalculateBearing(node.Point, option.Node.Point);
                    option.BearingDiff     = Math.Abs(bearing - prevBearing);
                    option.IsDeadEnd       = deadEndFound;
                    option.UnvisitedCount  = unvisitedNodesFound;
                    option.VisitedCount    = visitedNodesFound;
                    option.TotalVisitCount = totalVisitCount;
                    option.UnvisitedPct    = visitedNodesFound == 0 ? 100 : (double)unvisitedNodesFound / visitedNodesFound;

                    // Absolute score - number of new nodes scores high.
                    option.Score = (unvisitedNodesFound - totalVisitCount) + _rnd.Next(0, 5); // Add a little randomness

                    // Percentage score - small dead ends scores high.
                    //option.Score = ((unvisitedNodesFound + visitedNodesFound) / ((double)totalVisitCount + 1)) + _rnd.NextDouble() * 0.1; // Add a little randomness
                }

                // Scores should reflect the direction with the most unexplored nodes. Higher = better.
                //      If nothing was explored score = unvisitedNodesFound + visitedNodesFound
                //      If everything was explored exactly once, score = 1. Will go below 1 when visitcount gets bigger than 1.
                // If there are no detected unexplored areas nearby, prefer to go straight ahead to cover some ground quickly.
                bool preferStraight             = false;
                bool onlyAlreadyExploredOptions = !options.Any(x => x.Score > 1.0);
                if (onlyAlreadyExploredOptions)
                {
                    long minVisitCount = options.Min(x => x.Node.VisitCount ?? 0);
                    bool allEqual      = options.All(x => x.Node.VisitCount == minVisitCount);
                    if (allEqual)
                    {
                        preferStraight = onlyAlreadyExploredOptions && _rnd.NextDouble() < 0.9;
                    }
                    else
                    {
                        // All are already explored, but some have higher count than others. Pick from nodes with lowest count.
                        options = options.Where(x => x.Node.VisitCount == minVisitCount).ToList();
                    }
                }
                else
                {
                    // Pick best score
                    options = options.OrderByDescending(x => x.Score).ToList();
                }

                // Most of the time select element 0, but sometimes randomly select another
                int maxIdx      = options.Count > 1 ? 1 : 0;
                int selectedIdx = _rnd.NextDouble() < 0.75 ? 0 : _rnd.Next(0, maxIdx + 1);
                nextNode    = options[selectedIdx].Node;
                prevNode    = node;
                node        = nextNode;
                prevBearing = GeoMath.CalculateBearing(prevNode.Point, node.Point);

                double segmentMeters = GeoMath.MetersDistanceTo(prevNode.Point, node.Point);
                long   segmentMs     = (long)((segmentMeters / agent.MetersPerSecond) * 1000);
                newPath.Points.Add(node.Point);
                pathUnixMs += segmentMs;
                newPath.PointAbsTimestampMs.Add(pathUnixMs);
                pathMeters += segmentMeters;
                pathMs     += segmentMs;

                if (pathMs >= 60 * 10 * 1000) // 10 minutes per path
                {
                    break;
                }
            }

            //if (deadEndDebugSegments.Count > 0)
            //{
            //    string geo = GeoJsonBuilder.Segments(deadEndDebugSegments);
            //    await _blobStoreService.StoreText($"debug/skipped-deadends/deadends-{deadEndDebugSegments.Count}-{DateTime.UtcNow.Ticks}.json", geo).ConfigureAwait(false);
            //}

            //if (possibleWayoutDebugSegments.Count > 0)
            //{
            //    string geo = GeoJsonBuilder.Segments(possibleWayoutDebugSegments);
            //    await _blobStoreService.StoreText($"debug/possible-way-out/wayout-{possibleWayoutDebugSegments.Count}-{DateTime.UtcNow.Ticks}.json", geo).ConfigureAwait(false);
            //}

            await _worldGraph.StoreUpdatedVisitCounts().ConfigureAwait(false);

            newPath.PathMs          = pathMs;
            newPath.TileIds         = _worldGraph.GetLoadedTiles().Select(tile => tile.Id).ToList();
            newPath.EncodedPolyline = GooglePolylineConverter.Encode(newPath.Points);

            string newPathJson = JsonSerializer.Serialize(newPath);
            await _blobStoreService.StoreText(BuildPathPath(agentId), newPathJson, overwriteExisting : true).ConfigureAwait(false);

            //string geoJson = GeoJsonBuilder.AgentPath(newPath);
            //await _blobStoreService.StoreText(BuildGeoJsonPathPath(agentId), geoJson, overwriteExisting: true).ConfigureAwait(false);

            var clientPath = new AgentClientPath
            {
                MsStart         = newPath.PointAbsTimestampMs.First(),
                MsEnd           = newPath.PointAbsTimestampMs.Last(),
                EncodedPolyline = newPath.EncodedPolyline
            };
            string clientPathJson = JsonSerializer.Serialize(clientPath);
            await _blobStoreService.StoreText(BuildClientPathPath(agentId), clientPathJson, overwriteExisting : true).ConfigureAwait(false);

            await TryTakeSelfie(oldPath.Points).ConfigureAwait(false);
        }
예제 #18
0
        public AgentCommand NextCommand()
        {
            AgentCommand nextCommand = _behaviour.PickCommand();

            return(nextCommand);
        }
예제 #19
0
 /**
  * COMMANDS
  */
 public void ReceiveCommand(AgentCommand command)
 {
     throw new System.NotImplementedException();
 }