Betir Technology We didn't set out to re-write a Robocup client from scratch, but that's basically what we did. There were so many things we wanted to change as time went on, we decided to re-do the class structure and clean up the code as well, plus make it coding standard. First, we added a new TwoDVec class and QuickIntMath class. These two classes increased the speed of Betir dramatically. TwoDVec encompases the MathVector and AbsoluteMathVector classes in Biter. QuickIntMath is a set of integer functions that dramatically increases the speed of geometric functions. This was a trick borrowed from high performance graphics engines. Ball prediction and dashToPoint functions were re-written to take advantage of these functions. A second improvement made was that see information is parsed immediately when it is received. Behaviors only fire once every 100ms, but the parse functions are called whenever there is new data in the buffer. Also, whereas Biter would pick a random behavior to fire from the list of behaviors that can fire and aren't inhibited, Betir fires all of them. This requires a developer to be more careful when designing behaviors, but it allows for separate behaviors dealing with the head and view quality, as well as a parser for heard messages, to run concurrently with action behaviors. TauntBehavior is an example of a concurrent behavior (it doesn't really do anything useful, but it's just an example). The class structure in Betir was also cleaned up and encapsulated better. The object hierarchy is no longer as large as in Biter, and also allows for pieces to be removed and/or replaced easily. This was done for a class project in 784, Neural Information Processing. The decision maing algorithm in Player.java was replaced with a neural net that chose what behavior to fire depending on the input. The NeuralNet.java class was included in the Betir source code as an example. We also decided that instead of using rexexp, we would just save off the objects parsed in the see info as the ball, a teammate, a flag, etc. The RobocupEnvironment holds all this saved off data for use whenever you need it. Behavior Strategies We wanted to allow complex plays to arise from simple behaviors. Because of this, many of our behaviors are relatively simple. Our base behavior, KiddySoccerBehavior, encapsulates everything needed to create an agent that plays like the downloaded form of Biter. If it sees the ball, it runs to it. If it has the ball and sees the goal, it kicks to the goal, otherwise it turns to the goal. If it doesn't see the ball, it opens up it's view angle and turns until it can see it. All other behaviors are built on top of KiddySoccerBehavior. These include PassBehavior, CornerKickBehavior, and the behaviors that facilitate zone playing, such as StayPutBehavior and ReturnToZoneBehavior. One complex behavior was created, ShootGoalBehavior. This behavior would fire if the agent has the ball and is within a certain distance to the goal. It figures out where to shoot the ball depending on where the opposing team's goalie and defenders are. In the same sense, our goalie is relatively simple as well. He moves up and down, matching the predicted Y value of the ball as it approaches the goal. It does have it's own prediction functions, however, that save off the ball and extrapolate its next position if it gets into a situation where it isn't sure where the ball is on a certain timestep. Once he stops the ball by stepping in front of it, he catches it, moves to the corner of the box, and passes it using the same PassBehavior the regular players use. It was observed that complex plays do arise from simple behavioral interactions. One of our favorite plays was probably the factor that won the tournament for us. The position of the zonal players was optimal for the goalie to catch the ball, pass to the upper zone player, who would pass to an attacker, who would score while the opposing team was still around our goal. All this was accomplished without any communication between the agents. |
UML Diagram JavaDocs Home