Messages from and to the server use S-expressions (short for symbolic expressions) as their basic data structure. The basic idea of S-expressions is very simple: they are either strings, or lists of simpler S-expressions. They are probably best known for their use in the Lisp family of programming languages where they are used for both code and data.
An advantage of using S-expressions over other data formats is that it provides an easy to parse and compact syntax that is to some extent still readable by humans for debug purposes. It is further easy to add new sensors to the messages as the parser on the client side can easily ignore unknown parts.
Messages exchanged between client and server use the default ASCII character set, i.e. one character is encoded in a single byte. Further each individual message is prefixed with the length of the payload message. The length prefix is a 32 bit unsigned integer in network order, i.e. big endian notation with the most significant bits transferred first.
Once established, the server sends groups of messages to the agent that contain the output of the agent's perceptors, including any hinge positions of the model, any heard messages, seen objects, etc. The exact messages sent depend upon the model created for the agent. Details of effector messages are given on the perceptors page.
In response to these perceptor messages, the agent may influence the simulation by sending effector messages. These perform tasks such as moving hinges in the model. Details of effector messages are given on the effectors page.
The server exposes a network interface to any monitors, on TCP port 3200 by default.
This interface allows external processes to be periodically notified of the simulation's state for purposes of visualisation, logging, etc. In addition, the connected process may send various commands to the server for purposes of training or machine learning. These commands are not available to agents directly, nor are they allowed during competitive soccer simulation.
When a monitor connects to the Simspark server using the monitor protocol, the information arrives in the following order:
The server sends an environment information message followed by the full scene graph.
The server sends a game state message followed by the full scene graph.
The server keeps sending partial game state messages followed by a full or partial scene graph, depending on what has been updated lately. The rate at which the server sends messages by the monitor port is defined in the file spark.rb which is located in the installation directory.
Note that much of the information in this section comes from a paper written by Carlos Bustamante with Markus Rollmann and Joschka Boedecker in 2008. Additional information was obtained by observation of the source code in trainercommandparser.cpp.
Environment Information Message
The environment information message has the following structure:
The play mode is currently an integer which represents a certain type defined in plugin/soccer/soccertypes.h in the TPlayMode enum.
Scene Graph Header
The scene graph header contains information about the completeness of the scene graph and the version number, and has the following form:
(Name Version Subversion)
Name Can take two values:
RSG Stands for Ruby Scene Graph, and indicates that the scene graph is a full description of the environment.
RDS Stands for Ruby Diff Scene, and indicates that the scene graph is a partial description of the environment, i.e. it contains a bunch of empty nodes representing the structure of the scene graph, and some updated information about the nodes who have changed lately.
Version The main version number of the scene graph.
Subversion The subversion number.
Note that across different server versions the message format has changed although the version number used here has not (as of server 0.6.3)
(RSG 0 1) indicates that the scene graph is full with version 0.1
(RDS 0 1) indicates that the scene graph is partial with version 0.1
There are two cases in which the full state message is generated:
When a new client connects (SparkMonitor::GetMonitorHeaderInfo)
When one or more nodes are added or removed (e.g. on scene import, on agent connect/disconnect, etc.)
Here is an example of a scene graph header, as returned by rcssserver3d version 0.6.3:
(RSG 0 1)
Scene Graph Contents
The scene graph is a structure that arranges the logical and often spatial representation of a graphical scene. In Simspark, the scene graph is a tree with a root node defined to be at the origin <0; 0; 0> without rotation. Each node has one or more children. The position and rotation of each child is the multiplication of the transformation matrices from the root node down to the child node.
The monitor does not care about the specific objects (whether it's a goal or a ball). It knows about ''Meshes'', i.e. objects that are loaded from files or built into the simulator. Currently, Simspark uses files from the Blender 3d modeler for which there is an importer (see plugin/objimporter) and some built-in objects (sphere, box, and cylinder) that are constructed in the stdmeshimporter. The monitor protocol implementation is defined in plugin/sparkmonitor.
In the following sections, each node type is briefly described. Every non-leaf node is defined with nd which is an abbreviation for node. For more information about abbreviations, see abbreviations.
It is important to mention that when the message represents an update to the scene graph, the scene graph omits node types and node information. In other words, the structure remains unchanged, but the message will be full of empty nd nodes, except for those nodes which are being updated.
Every node type which is not a transform node, a static mesh node or a light node, is considered a base node (including the root node). Base nodes do not have a description in the message, they are simply used for preserving the structure of the scene graph. They can contain any number of child nodes. A base node has the following form:
(nd BN <contents>)
A transform node represents a 4x4 homogeneous transformation matrix which is commonly used in robotics and computational geometry for representing geometric transformations. A transformation matrix defines how to map points from one coordinate space into another coordinate space, by defining a translation, a rotation and a scaling factor. The scaling factor is considered 1 for most applications.
The typical form of a homogeneous transformation matrix is as follows:
[nx ox ax Px][ny oy ay Py][nz oz az Pz][ 0 0 0 1]
where the unit vectors n; o; a stand for normal, orientation and approach, respectively, and refer to the three vectors that represent a reference frame in the three dimensional space.
A transform node in Simspark representing the aforementioned transformation matrix is as follows:
(nd TRF (SLT nx ny nz 0 ox oy oz 0 ax ay az 0 Px Py Pz 1))
Where SLT represents a SetLocalTransform leaf node, which is a ruby function for setting the local transformation of a given node in the scene graph.
The following two node types describe object shapes. They specify its scale and its material (texture). They have no child nodes (they are leaves).
A light node describes the way in which lights affect the object. Specifically, the diffuse, ambient and specular lights are defined. It has the following form:
(nd Light (setDiffuse x y z w) (setAmbient x y z w) (setSpecular x y z w))
where <x; y; z> is a vector defining the light direction and w is a scaling factor. Each of the leaf nodes is described below:
setDiffuseDiffuse reflection is the reflection of light from an uneven or granular surface such that an incident ray is seemingly reflected at a number of angles. It is the complement to specular reflection.
setAmbientAmbient light (also available light or existing light) refers to the illumination surrounding a subject or scene.
setSpecularSpecular reflection is the perfect, mirror-like reflection of light (or sometimes other kinds of wave) from a surface, in which light from a single incoming direction (a ray) is reflected into a single outgoing direction.
Monitor Protocol Abbreviations
The monitor protocol uses abbreviations of terms for describing the environment, with the objective of saving bandwidth when sending messages to the connected clients. Here is a list of the meanings of the most important abbreviations:
BN Base Node
TRF Transform Node
SLT SetLocalTransform Leaf Node
SMN StaticMesh Node
sSc SetScale Leaf Node
sMat SetMaterial Leaf Node
RSG RubySceneGraph Node : Full State
RDS RubySceneGraph Node : Update
Command Messages from Coach/Trainer
A monitor may be used by a referee during a competition to enforce rules of the game that are not currently catered for by the simulation. Additionally, machine learning processes may send commands to influence the environment in special ways to improve the speed or quality of learning exercises.
When debugging an application that sends these messages to the server, check the server console or log file for error messages. Errors are not returned to the caller.
Note that sending a command may have no effect in certain play modes. For example, moving the ball away from the center position in BeforeKickOff mode is immediately counteracted by the simulator.
Moving an Agent
You can either move an agent, or move and rotate it. Additionally, you can set the battery level and temperature.
unum and team must both be specified, but the remainder are optional. Zero or more operations may be applied to the specified agent via this command.
x, y, z are absolute values in field coordinates. That is, (0,0) is the centre of the field.
TODO what units are in? again, relative or absolute?
Positioning the Ball
The ball may be repositioned and optionally given an explicit velocity as well.
(ball (pos <x> <y> <z>) (vel <x> <y> <z>))
pos and vel are both optional, though if neither are included, then no change is made. Note that setting the velocity of the ball will also reset any angular velocity of the ball to zero.
Setting the Play Mode
The play mode may be manually set to an explicit value.
Where <playmode> is one of the predefined, case sensitive, play mode values. Possible play modes are given as strings in the play_modes expression of the init expression the monitor receives when it connects.
TODO link to these values as they're elsewhere on this wiki
Drop the Ball
Drops the ball at its current position and move all players away by the free kick radius. If the ball is off the field, it is brought back within bounds.
This operation has no arguments.
Assigns a soccer kickoff to the specified team.
Where <team> is one of Left, Right, None. If None is passed, a coin is tossed to select a team.
(select (unum <num>) (team <team>))
Where <team> is one of Left, Right, None.
If unum and/or team are not specified, then the next agent is selected.
Only one agent may be selected at a time. TODO confirm this.
Selection can be used with the kill and reposition commands.
Removes the specified agent from the simulation.
(kill (unum <num>) (team <team>))
Where <team> is one of Left, Right, None.
If unum and/or team are not specified, then the selected agent is killed.
Repositioning an Agent
Repositions the specified agent to a calculated location. TODO explain how this new location is calculated, and under what circumstances in a game this would be used.
(repos (unum <num>) (team <team>))
Where <team> is one of Left, Right, None.
If unum and/or team are not specified, then the selected agent is repositioned.
(getAck <cookie string>):
Experimental feature, currently disabled. Requests an ack reply from the server. The server will send the answer as soon as the command is carried out. This is used to synchronize a trainer implementation with the server. The getAck expression is appended behind one of the above commands.