EISMASSim is based on the Environment Interface Standard (EIS), a proposed standard for agent-environment interaction.
It maps the communication between agents and the MASSim server, (i.e. sending and receiving JSON messages), to Java method calls. Also, it automatically establishes and maintains connections to a specified MASSim server.
In other words, EISMASSim is a proxy environment on the client side which handles communication with the MASSim server completely by itself.
EISMASSim is packaged as a jar file eismassim-X.Y-jar-with-dependencies.jar
which already includes the EIS package. The easiest way would be to include the jar with dependencies in your classpath. If you want to manage dependencies yourself, use eismassim-X.Y.jar
. You can get the required EIS version (0.5.0) from the eishub.
EnvironmentInterfaceStandard ei = new EnvironmentInterface();
The environment interface needs a configuration file to know how many entities it has to create. In the above case, an eismassimconfig.json
file is expected in the working directory. Alternatively, the path to a configuration file can be given to the constructor.
try {
ei.start();
} catch (ManagementException e) {
// TODO handle the exception
}
This sets the state of the interface to RUNNING
.
Each agent you want to connect needs to be registered with the interface.
try {
ei.registerAgent(agentName);
} catch (AgentException e) {
// TODO handle the exception
}
Entities are the corporeal parts used for perceiving and acting, i.e. the vehicles in the simulation. The available entities are specified in the eismassimconfig.json
file which needs to match the MASSim scenario requirements.
try {
ei.associateEntity(agentName, entityName);
} catch (RelationException e) {
// TODO handle the exception
}
This part automatically triggers authentication of the associated entity with the MASSim server.
Percepts can either be polled or received as notifications.
try {
eis.getAllPercepts(agentName);
} catch (PerceiveException e) {
// TODO handle the exception
}
This would retrieve all percepts for the agent named agentName
. The return value is a map, since the agent could be associated with more than one entity.
Action action = new Action(...);
try {
ei.performAction(agentName, action);
} catch (ActException e) {
// TODO handle the exception
}
To execute an action, the name of the agent executing the action and the action itself need to be passed. All entities associated with the agent will perform this action (if possible).
The configuration of EISMASSim is now realized with JSON files, matching the configuration of the MASSim server.
Configuration example:
{
"scenario": "assemble2019",
"host": "localhost",
"port": 12300,
"scheduling": true,
"timeout": 40000,
"times": false,
"notifications": false,
"queued": false,
"entities": [
{
"name": "connectionA1",
"username": "agentA1",
"password": "1",
"print-iilang": false,
"print-json": true
},
...
]
}
In the above example, only one entity is configured for the sake of readability. (Usually, way more entities are listed there.)
The main entries are:
- scenario: the name of the MAPC scenario to handle
- host: address of a MASSim server
- port: port the MASSim server is listening on
- scheduling: if
true
, an action can only be sent if a valid action-id is available; calls toperformAction
will also block until such an ID becomes available; it is recommended to not disable this - timeout: the timeout to use in combination with scheduling while waiting for
performAction
- queued: if enabled,
getAllPercepts
will only yield one collection of percepts for each call (i.e. one for all percepts from aSIM-START
message, one for all percepts from aREQUEST-ACTION
message, etc.) in the same order as they were received from the MASSim server - times: if enabled, percepts will be annotated with the time they were generated by the server
- notifications: if enabled, percepts will be delivered as notifications; this is detailed in the description of EIS
Further, there is an object for each entity in the entities
array, containing
- name: the name of the entity
- username: the name to authenticate with
- password: the password to authenticate with (both as configured in the MASSim server)
- print-iilang: whether to print the IILang version of received percepts
- print-json: whether to print JSON messages sent and received by the interface
EISMASSim is exemplarily used in the javaagents package.
Actions and percepts in EISMASSim use the Interface Intermediate Language (IILang) as provided by EIS. The IILang defines the following concepts:
- DataContainer: consists of a name and a number of Parameters
- Action: used for acting
- Percept: used to perceive changes in the environment
- Parameter: argument to DataContainers
- Identifier: contains a string value
- Numeral: contains any number value
- TruthValue: contains a boolean value
- ParameterList: strangely, a list of parameters
- Function: has the same structure as a DataContainer, but can be used as a Parameter
Thus, any IILang DataContainer forms a tree structure that can also be represented with Prolog-like syntax. For example, car(red, 2007, [ac, radio], wheels(4))
could be a Percept with the name car
, an Identifier (parameter) red
, a Numeral 2007, a ParameterList containing 2 Identifiers and a Function named wheels
containing a final Numeral.
The actions for the current scenario can be reviewed in scenario.md. An IILang action takes a name and a number of parameters. Just pass the required parameters in the same order as described in scenario.md.
Example:
Action a = new Action("move", new Identifier("n"));
The following paragraphs describe how the JSON messages described in protocol.md and scenario.md are translated into IILang percepts.
[XYZ, ...]
denotes a ParameterList of arbitrary length
The following percepts might be included in a SIM-START
message:
name(s)
- s : Identifier - name of the agent
team(s)
- s : Identifier - name of the agent's team
steps(n)
- n : Numeral - number of steps
vision(n)
- n : Numeral - initial vision of the agent
The following percepts might be included in a REQUEST-ACTION
message. Most of them should be self-explanatory.
actionID(id)
- id : Numeral - current action-id to reply with
timestamp(time)
- time : Numeral - server time the message was created at
deadline(time)
- time : Numeral - when the server expects the action
step(number)
- number : Numeral - the current step
lastAction(type)
- type : Identifier - name of the last executed action
lastActionResult(result)
- result : Identifier - result of the last executed action
lastActionParams([p1, ...])
- p1 : Identifier - first parameter of the last executed action
score(n)
- n : Numeral - the team's current score
thing(x, y, type, details)
- x/y : Numeral - relative position of a thing
- type : Identifier - the type of the thing
- details : Identifier - possibly more information about the thing (see scenario doc)
task(name, deadline, reward, [req(x,y,type),...])
- name : Identifier
- deadline : Numeral - the last step the task can be completed
- reward : Numeral
- req : Function - a required block for the task
- x/y : Numeral - the relative position of the required block
- type : the type of the block
<terrainType>(x, y)
<terrainType>
is one of the possible terrains (obstacle
,goal
, ...)- x/y : Numeral - the relative position of the terrain
attached(x, y)
- x/y : Numeral - relative position of a thing that is attached to some entity
energy(n)
- n : Numeral - the agent's energy level
disabled(b)
- b : Identifier - true if the agent is disabled (else false)
The following percepts might be included in a SIM-END
message:
ranking(r)
- r : Numeral - the final ranking of the agent's team
score(s)
- s : Numeral - the final score of the agent's team