RoboJackets / robocup-software

Georgia Tech RoboJackets Software for the RoboCup Small Size League
Apache License 2.0
183 stars 187 forks source link

Implement Gameplay Evaluators for Situation Analysis (or decide not to) #1603

Open liquidmetal9015 opened 4 years ago

liquidmetal9015 commented 4 years ago

Description

With the gameplay rewrite we are re-writing much of our evaluation code to follow a design where the world-state is passed in as an argument and operated on directly by the evaluation code from there. This keeps our data-flow linear and downwards which has a lot of upsides in the way it de-couples these functions from the rest of the gameplay system.

In the transfer to the new system we need to implement situation analysis to fulfill the same roll it did before, to categorize the current moment into a "situation" to narrow down play selection to only plays designed for that situation. The idea is that this is evaluation code, but it cannot run on an "World State in, Evaluations Out" design like our other code will be able to because the current design tracks events over multiple frames to determine the situation.

The proposed design to handle this is to create a class of objects called "Evaluators" which are evaluation code that continually runs operating on the WorldState each frame. They would have a function something like def tick(WorldState): -> None that would be called on the new WorldState each frame. This presents some issues though, as if a play accesses information from an evaluator directly, that would couple that play to only work when that evaluator has been fed with the past WorldStates via tick and can provide accurate information.

A couple of ways we could respond to this:

  1. Package the output from evaluators in some way and feed it into plays from the top down, like how WorldState is fed in top down. This would allow for evaluator states to be fed in during tests and potentially recorded along with WorldState.

  2. Not have evaluators - Two points here

    a. Situation Analysis is the guiding example behind the idea of creating evaluators, but we could break out as much as possible into "World State in, Evaluations Out" functions and then put any necessary filtering or multi-frame functions in some special case somewhere else, or try to have play selection deal with the noise that may arise from single-frame evaluation of situation. I might be able to write better single-frame situation analysis logic by paying closer attention to the velocity of various bodies (assuming velocities are not very noisy).

    b. The other key question is are we going to have other functionality that could be fulfilled by evaluators. It seems like the main thing that cannot be done without this type of evaluation is evaluation with regards to time, asking questions like "how long has it been since we last had the ball in the mouth of our robot" which seems to mostly impact the filtering of evaluations. These types of evaluations are used in situation analysis to filter the situation by, for example, waiting a moment before declaring the ball is possessed, no longer possessed, is wedged between two robots, etc.

  3. Use some other design to make evaluators more ergonomic or get around implementing them. I have some vague ideas but am interested what people think.

There also remains the question of when to run what evaluators if we have a number of them. If one is needed only for one play and is computationally expensive do we run it at all times?

Requirements

liquidmetal9015 commented 4 years ago

So based on the input from the 11/10/2020 meeting from @kylestach the plan is to implement this in the naive way for right now and then possibly put evaluator results into the context object or find a better solution.

It's generally agreed that trying to do situation analysis and other systems statelessly would make them too brittle and difficult to change on the fly.