?? _tutorial.tex
字號(hào):
\chapter{Tutorial}\label{chTutorial}The BATS agent architecture consists of several parts and layers. This tutorial guides you through using these parts step by step. All lower layers are independent of the higher layers. So if you don't need all, you can skip the later sections. If you are only interested in an easy interface with the simulation server, reading section \ref{secSocketComm} will suffice. If you want to start quickly with a working agent, you can skip until section \ref{secHumanoidAgent} for now. However, the agent template described there is based on the elements described in the sections before that, so be sure to read those too at some time, to fully understand how your agent works.\section{SocketComm}\label{secSocketComm}The lowest layer in our architecture manages the communication with the simulation server. This communication is done through TCP sockets and consists of S-expressions (predicates) that the agent and server send back and forth. The SocketComm handles the connection to the server and sending, receiving and parsing of the messages.When creating a SocketComm you have to supply a hostname and a port number to connect to. When running the server on the same computer as your agent with default settings, these are 'localhost' and '3100'. After creating a SocketComm, the first thing to do is open an actual connection by calling connect:\begin{program}\begin{verbatim}SocketComm comm("localhost", 3100);comm.connect();\end{verbatim}\end{program}The SocketComm keeps two internal message queues, one for input and one for output. These queues are filled and emptied, respectively, when calling SocketComm's update method. This call blocks until new data is received from the server:\begin{program}\begin {verbatim}comm.update();\end{verbatim}\end{program}SocketComm supplies several methods to place messages that should be sent to the server into the output queue. First of all, you can build your own predicate using the Predicate and/or Parser classes \footnote{This method is not described in this HowTo. Look at the documentation in the source code for more info} and put it directly into the queue by calling the send method:\begin{program}\begin{verbatim}rf<Predicate> myPredicate = makeMyPredicate();comm.send(myPredicate);\end{verbatim}\end{program}However, you can also leave the trouble of building the predicates to SocketComm by using the make*Message methods. These methods are also used by the init, beam and move* methods, which also place the messages directly into the queue for you.The input queue holds the messages received from the server. To check whether there is a new message you can call hasNextMessage, to extract the next message you can use nextMessage:\begin{program}\begin{verbatim}while (comm.hasNextMessage()) rf<Predicate> message = comm.nextMessage();\end{verbatim}\end{program}To conclude this section we present a typical way to have successful communication with the server:\begin{program}\begin{verbatim}// Create the SocketComm and connectSocketComm comm("localhost", 3100);comm.connect();// Wait for the first message from the servercomm.update();// Identify yourself to the servercomm.init(0, "MyTeam");// Main loopwhile (true){ comm.update(); while (comm.hasNextMessage()) handleMessage(comm.nextMessage());}\end{verbatim}\end{program}\section{WorldModel}\label{secWorldModel}The SocketComm parses the S-expressions that the agent receives from the server into our Predicate structure. However, to extract useful data and keep a model of the world you still have to dig through these messages. In our architecture, WorldModel does exactly this, helping you avoid handling S-expressions/predicates completely on the input side. The WorldModel is a singleton object that encapsulates the SocketComm and provides a large number of methods to determine the world state.Before the WorldModel can be used, it has to be initialized by supplying a SocketComm that is connected to the server. To use the WorldModel, you have to get a reference to the singleton object:\begin{program}\begin{verbatim}WorldModel::initialize(comm);WorldModel& wm = WorldModel::getInstance();\end{verbatim}\end{program}The {\tt WorldModel} should be updated at the beginning of every time step. This updates the {\tt SocketComm} (so you don't have to call {\tt SocketComm::update()} yourself anymore), reads all messages from them and updates the internal model according to them:\begin{program}\begin{verbatim}wm.update();\end{verbatim}\end{program}After this you can request the states of the game, the world and the agent itself by calling WorldModel's methods. For a description of these, please look at the documentation of the source code.\section{Cerebellum}\label{secCerebellum}The same way WorldModel keeps you from having to work with predicates on the input site, the Cerebellum overlays the output interface. It supplies more useful structures to define actions and the possibility to integrate actions from different sources in your agent. The Cerebellum has the Action substructure and a few of its derivatives with which you can make new actions. At the moment there are 4 different usable action types:\begin{itemize}\item {\tt MoveJointAction} - Move a hinge joint or one axis of a universal joint\item {\tt MoveHingeJointAction} - Move a hinge joint\item {\tt MoveUniversalJointAction} - Move both axes of a universal joint\item {\tt BeamAction} - Beam to a certain position\end{itemize}The Cerebellum is, also like the WorldModel, a singleton that can be retrieved by calling {\tt Cerebellum::getInstance()} after which you can add actions to the Cerebellum. After all the sub parts have added their actions, you can call {\tt outputCommands()} to send the collections through a SocketComm:\begin{program}\begin{verbatim}Cerebellum& cer = Cerebellum::getInstance();rf<MoveJointAction> action = new MoveJointAction(Types::LLEG1, 0.1);cer.addAction(action);cer.outputCommands(comm);\end{verbatim}\end{program}When more than 1 action is supplied for a hinge joint or part of a universal joint, the given speeds will be averaged before sending to the server.\section{HumanoidAgent}\label{secHumanoidAgent}As said above, this section will show how to quickly set up an agent that connects to the server, reads and parses messages that come from it and has a think cycle in which you can easily send actions back. This is done by using the {\tt HumanoidAgent} class. It combines the classes described in the previous sections and creates an easy interface for new agents. To use it, you should create a class that inherits from it:\begin{program}\begin{verbatim}class MyAgent : public bats::HumanoidAgent{ public: MyAgent(std::string teamName) : bats::HumanoidAgent(teamName) {}};\end{verbatim}\end{program}As you see, the constructor of the {\tt HumanoidAgent} class expects a team name. You can also give it a host name and port to use to connect to and a uniform number. By default the latter is set to 0, meaning that the server picks a free uniform number. To run the agent, all you have to do is make a new object of your agent class and call the {\tt run()} method on it:\begin{program}\begin{verbatim}int main(){ MyAgent agent("MyTeam"); agent.run();}\end{verbatim}\end{program}This runs the initialization code of the {\tt HumanoidAgent}, which connects it to the server, sends the needed initialization message, and calls the {\tt init()} method. Overload this method if your agent needs its own initialization code. After this, an infinite loop is started that updates the {\tt WorldModel} and calls the {\tt think()} method at each time step. If you want your agent to actually do something, overload this last method.\section{Behavior}\label{secBehavior}The code in the previous section implements an agent which connects to te server, gets placed in the field and then stands there until it falls over. Now it is time to let your agent behave. The BATS agent architecture supplies a hierarchical behavior model to help you with this by following these steps:\begin{itemize}\item Implement seperate behaviors\item Create a configuration file placing the behaviors in a hierarchical structure\item Create and run the behaviors\end{itemize}\subsection{Implementing a behavior}\label{subsecImplementingBehavior}The BATS agent architecture gives the {\tt Behavior} class as the building block of your agent. The basic thing to know is that a behavior receives a goal from a higher level behavior, creates subgoals that it wants to achieve in order to achieve the main goal and passes these goals to its subbehaviors. The behavior defines a sequence of slots in which arbitrary sub behaviors can be placed. This section shows how to create a behavior, section \ref{subsecConfiguration} will show how to define its super and sub behaviors.\subsubsection*{Inherit Behavior}The first thing to do when creating a new behavior is to create a class that inherits from the {\tt Behavior} class. It defines a couple of pure virtual methods that each behavior should implement (more on these later):\begin{program}\begin{verbatim}class MyBehavior : public Behavior{ virtual rf<Goal> generateGoal(unsigned step,
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -