AgentSpeak - custom agents and actions
In these practicals, we will use one of the more complex Jason examples. First, we will show how to implement custom world model and how to add custom internal actions.
You can find the source codes for this lesson in the Jason distribution in the examples/gold-miners-II
directory. It is an older scenario from a multi-agent competition. There are two teams of six agents and a leader. The agents move in the environment and their goal is to mine gold. Every agent can carry at most three pieces of gold and they have to carry it towards a warehouse. They try to get as many pieces of gold as possible before the other team.
Custom agent architecture
So far, we used the default functions for the processing of messages and precepts and the environment was represented with the information in the belief base. Such an implementation is simple, but not very convenient in more complicated cases. Therefore, Jason allows us to create a custom agent architecture. We can provide methods for the processing of percepts and incoming messages; we can write custom internal actions (because some things are easier in Java than in AgentSpeak) and we can create our own representation of the environment (so that we can, for example, more easily implement the A* algorithm for pathfinding).
In order to create a custom agent architecture, we need to implement the AgArch
class. In this class, we can redefine the java.util.List<Literal> perceive()
and void checkMail()
methods (and others).
We redefine the checkMail()
method if we want to process some messages in a specific way. In the example, the messages about obstacles and agents’ positions are removed and the model is updated according to them. Thanks to this, the agent is able to process more than one message in each loop instead of only one. At the same time, we correctly update the internal representation of the environment (see arch/MinerArch.java
).
We can also re-define the perceive()
method for similar reasons. In the example, again, the method processes all the percepts and updates the model of the environment. It keeps only those percepts the agents needs to act upon in the queue (arch/LocalMinerArch.java
, and methods from arch/MinerArch.java
).
The agents use a copy of the environment as their internal representation. They use it to represent what they know about the environment, either from messages or from their own percepts (arch/LocalWorldModel
).
The architecture used by the agent is specified in the .mas2j
file as agentArchClass
(see the example).
Custom BeliefBase
Sometimes it is convenient to change the behavior of the belief base in a specific way. This can be done by implementing a new offspring of the DefaultBeliefBase
class with a custom add
method. There are two such classes in the example – one of them ensures that a belief with the same functor is presented only once in the belief base (it is automatically updated when a new belief with the same functor is added), the other ensures that some beliefs are discarded before they are even added to the belief base (the agent does not care about these as they are already represented in the model of the environment). For the implementation details see agent/UniqueBelsBB.java
and agent/DiscardBelsBB.java
.
The belief base used by the agent is again specified in the .mas2j
file – as beliefBaseClass
.
Custom event selection function
In some cases we need to change the event selection function. For example in such a way that some events have priority over other ones. One of the example agents uses this approach to quickly react to any new gold that is discovered (this event thus has the highest priority). In case we want to change these functions, we need to implement a custom Agent
class.
The agent class is specified in the .mas2j
file and an example of such a class is in the agent/SelectEvent.java
file.
Custom internal actions
Agent’s internal actions can be used to change its internal representation, communicate with other agents, or do anything that is easier in Java than AgentSpeak (e.g. pathfinding).
In order to create a custom internal action, you need to implement a DefaultInternalAction
class and its execute()
method. The method has three parameters, one of them is TransitionSystem
, which contains the information about the agent’s environment representation and its internal state. Another parameter is a unifier, which use can use to unify variables with variables in AgentSpeak and the last parameter is a list of Term
s – the parameters of the action. Again, it is easier to look at the examples, you can find them in the jia
directory. One of the simpler actions is obstacle
, which indicates whether there is an obstacle at a given position.
Assignment
In this assignment, the goal is to implement the strategy for the goal-miners-II
scenario described above.
The environment is a square grid, where some locations contain gold, other locations can contain obstacles. One of the locations is a depot, where the agents take all the gold. It is in the same location for both teams. The agent mines the gold by executing the pick
action, it can drop it by executing the drop
action (if it drops the gold at the depot, its team gets a point for every piece of gold dropped). Each agent can carry at most three pieces of gold at the same time.
The environment provides the following actions:
pick
- pick the gold from the position where the agent standsdrop
- drop the gold to the position of the agentup
,down
,right
,left
- move one square in the respective direction
The actions are called as do(<action>)
, e.g. do(drop)
.
In the beginning of the simulation, the agents receive the following percepts:
gsize(sID, W, H)
- the environment for simulation with IDsID
has widthW
and heightH
depot(sID, x, y)
- the depot in simulation with IDsID
is atx
,y
steps(sID, n)
- simulation with IDsID
will run forn
steps
During the simulation, the environment provides the following percepts:
pos(x,y,s)
- in steps
the agent is at position(x,y)
cell(x,y,t)
- at position(x,y)
there is thingt
(obstacle
,gold
,enemy
,ally
,empty
) for all locations around the agent (up to distance 1)container_has_space
- agent can carry more goldcarrying_gold(n)
- agent carriesn
pieces of gold
The agents also have fatigue, which determines the probability that percepts fail (i.e. agent does not get any new information in a given step) and the probability that actions fail (the action is not executed). The fatigue of an agent depends on the amount of gold it carries (linearly between 0.1 and 0.5 for 0-3 pieces of gold).
Rules and Tips
You can use the example agents for inspiration, but try to implement the final strategy yourself. You can work in teams of up to 4 students. Choose a name for your team and use it as a prefix to all the files you submit.
There are two methods that can be useful = .send
and .broadcast
that send a message to a specific agent or to the whole team (respectively). The .send
method has three parameters
- the receiver,
- the performative (what the message in) -
tell
for information,achieve
for request, anduntell
for information that should be removed, and - the content.
The .broadcast
action has only the last two parameters. The .broadcast
action in the example contains a bug and sends the message only to the first three agents on your team – you can fix it by re-implementing it (create a new version of arch/MinerArch.java
and all classes that depend on it), or by creating a plan in AgentSpeak to explicitly .send
the message to all agents.
Typically, the content is formatted as AgentSpeak facts (i.e. the same way percepts are coded), and by default it is saved in agents belief base with a source annotation.
Points
Each member of a team will obtain 8 points if the team submits any strategy that beats the dummy agents implemented in the asl
directory of the example. We will run a tournament and the four best strategies (from both groups combined) will get 10 points. (The number of teams that get the bonus points can be increased in case we have a lot of teams.)
Deadline: April 8, 2024