Jadex offers the possibility to change the underlying agent and capability models at runtime, i.e. it is e.g. easily possible to define new beliefs, goals and plans and the like at runtime. For this purpose every capability and agent instance owns it own copy of the underlying model. In this respect changes to a model remain local to the corresponding capability or agent instance, and the original model contained in the ADF will never be changed this way.
The process for creating model elements at runtime is very simple in principle. It consists of two steps:
Create the model element in the model. Regardless, which element should be created it is necessary to fetch the corresponding model element that belongs to the current scope (capability):
IMCapability model = (IMCapability)getScope().getModelElement();
Depending on which element you want to create you can access
e.g. the different bases such as the planbase and create a
new model element via the various create...()
methods. For a detailed overview consider looking into the API
docs of the Jadex model accessible through the interfaces contained
in the jadex.model
package.
Register the model element at the runtime.
To make the runtime aware of the new element it is necessary to
call one of the register...()
methods at the
corresponding runtime bases (or the capability itself).
Similarly, it is possible to delete elements from the model in two steps:
Deregister the model element at the runtime.
To clean-up the element at runtime the suitable
deregister...()
method should be
called.
Delete the model element from the model. Again, it is necessary to have access to the model layer via:
IMCapability model = (IMCapability)getScope().getModelElement();
Depending on which element you want to delete you can access
e.g. the different bases such as the planbase and delete an
existing model element via the various delete...()
methods.
Using the model API (package jadex.model
)
plans can dynamically load and unload capabilities. To load a
capability, you first have to create a so called capability reference
in the agent (or capability) model. The createCapabilityReference()
method works the same as the <capability>
tag
shown in Figure 5.3, “Including subcapabilities”, and therefore expects the local
name of the subcapability and a filename.
After creating the reference, which also loads the given XML file,
you can register the new capability at runtime (this will initialize the capability by
creating initial goals, plans, etc.).
To use the features of the capability you can also dynamically add references
to the exported beliefs and goals of the capability. Figure 14.1, “Adding a capability at runtime”
shows how to include a capability at runtime.
public void body() { // Create reference in the model. IMCapability model = (IMCapability)getScope().getModelElement(); IMCapabilityReference subcap = model.createCapabilityReference("dfcap", "jadex.planlib.DF"); // Register capability at runtime. getScope().registerSubcapability(subcap); ... }
Figure 14.1. Adding a capability at runtime
The removal of a capability can be done likewise. In Figure 14.2, “Removing a capability at runtime” an example code is depicted.
public void body() { ... IMCapabilityReference subcap = ((IMCapability)getScope().getModelElement()) .getCapabilityReference("subcap_name"); // Deregister subcapability at runtime. getScope().deregisterSubcapability(subcap); // Delete subcapability from the model. ((IMCapability)getScope().getModelElement()).deleteCapabilityReference(subcap); ... }
Figure 14.2. Removing a capability at runtime
Usually all agent beliefs are defined in the ADF. At runtime only
the facts contained in the beliefs change, not the beliefs themselves.
The model API (package jadex.model
)
allows to dynamically create new beliefs and belief sets at runtime,
if this self-modifying functionality is required.
To create a new belief, it first has to be defined in the agent or
capability model. The createBelief...()
methods
of the IMBeliefbase
work the same as the
belief/set/reference tags shown in Figure 6.1, “The Jadex beliefs XML schema part”.
For beliefs and belief sets a name, class, update rate and exported flag
have to be specified. For belief(set) references instead of an update rate
the path of the referenced belief(set) has to be provided.
After creating a belief(set) or reference in the model, you have to register the new element at runtime (this will also evaluate the initial facts, if you have supplied some in the model). Figure 14.3, “Creating a belief at runtime” shows how to create a belief at runtime.
public void body() { ... // Create belief in the model. IMBeliefbase model = (IMBeliefbase)getBeliefbase().getModelElement(); IMBelief belief = model.createBelief("name", String.class, -1, false); // Register belief at runtime. getBeliefbase().registerBelief(belief); ... // Access the belief as usual. getBeliefbase().getBelief("name").setFact("Hugo"); ... }
Figure 14.3. Creating a belief at runtime
In Figure 14.4, “Deleting a belief at runtime” it is shown how a belief can be deleted at runtime.
public void body() { ... IBelief belief = getBeliefbase().getBelief("belief_name"); IMBelief mbelief = (IMBelief)belief.getModelElement(); // Deregister the belief at runtime. getBeliefbase().deregisterBelief(mbelief); // Delete the belief in the model. IMBeliefbase model = (IMBeliefbase)getBeliefbase().getModelElement(); model.deleteBelief(mbelief); ... }
Figure 14.4. Deleting a belief at runtime
Usually all goal types (like, e.g., “performpatrol”) are defined in the ADF. At runtime instances
of these types are created, but the set of available goal types remains the same.
The model API (package jadex.model
)
allows to dynamically create new goal types and goal references at runtime,
if this self-modifying functionality is required.
To create a new goal type, it first has to be defined in the agent or capability model.
The create...Goal()
and create...GoalReference()
methods of the IMGoalbase
work the same as the tags shown in Figure 7.1, “The Jadex goals XML schema part”.
For goals, a name, exported flag, retry, retry delay, and exclude mode
are required. Maintain goals require in addition the specification of recur and recur delay.
For references, the name, the exported flag, and the path to the referenced goal
have to be specified.
After creating a goal or reference in the model, you have to register the new element at runtime (this will also activate the creation condition, if you have supplied one in the model). Figure 14.5, “Creating a new goal type at runtime” shows how to create a new goal type at runtime.
public void body() { ... // Create goal type in the model. IMGoalbase model = (IMGoalbase)getGoalbase().getModelElement(); IMGoal goal = model.createPerformGoal("performpatrol", false, true, -1, IMGoal.EXCLUDE_NEVER); goal.createContextCondition("!$beliefbase.is_loading && !$beliefbase.daytime"); // Register goal at runtime. getGoalbase().registerGoal(goal); ... }
Figure 14.5. Creating a new goal type at runtime
An example for the deletion of a goal type at runtime is shown in Figure 14.6, “Deleting a goal type at runtime”.
public void body() { ... // Assuming that mgoal is the model of the element to be deleted // Deregister goal at runtime. getGoalbase().deregisterGoal(mgoal); // Delete goal type from the model. IMGoalbase model = (IMGoalbase)getGoalbase().getModelElement(); model.deleteAchieveGoal((IMAchieveGoal)mgoal); ... }
Figure 14.6. Deleting a goal type at runtime
Adding new plan specifications to the agent or capability at runtime is similar
to what has already been described for beliefs and goals.
First the plan head has to be created using the API of the
jadex.model
package.
Afterwards, the plan has to be registered at runtime, mainly
for activating the plan trigger.
public void body() { ... // Create plan type in the model. IMPlanbase model = (IMPlanbase)getPlanbase().getModelElement(); IMPlan plan = model.createPlan("ping", 0, "new PingPlan()", IMPlanBody.BODY_STANDARD); plan.createTrigger().createMessageEvent("query_ping"); // Register plan at runtime. getPlanbase().registerPlan(plan); ... }
Figure 14.7. Creating a new plan type at runtime
In the following the deletion of a plan type is sketched (see Figure 14.8, “Deleting a plan type at runtime”).
public void body() { ... // Assuming that mplan is the model of the element to be deleted // Deregister plan at runtime. getPlanbase().deregisterPlan(mplan); // Delete plan type in the model. IMPlanbase model = (IMPlanbase)getPlanbase().getModelElement(); model.deletePlan(mplan); ... }
Figure 14.8. Deleting a plan type at runtime
In general it is possible to create custom events at runtime. This applies for goal, message as well as internal events. Nevertheless, as goal events are used only internally creating message and internal events should be the only relevant use case.
In Figure 14.9, “Creating a new internal event type at runtime” an example is depicted how a new internal event can be created and registered.
public void body() { ... // Create event type in the model. IMEventbase model = (IMEventbase)getEventbase().getModelElement(); IMInternalEvent ievent = model.createInternalEvent("new_ievent", false); ievent.createParameter("param1", String.class, IMParameter.DIRECTION_IN, 0, null, null); // Register event at runtime. getEventbase().registerEvent(ievent); ... }
Figure 14.9. Creating a new internal event type at runtime
In Figure 14.10, “Deleting an internal event type at runtime” the removal of an internal event at runtime is outlined.
public void body() { ... // Assuming that imevent is the model of the event to be deleted // Deregister event at runtime. getEventbase().deregisterEvent(imevent); // Delete event type in the model. IMEventbase model = (IMEventbase)getEventbase().getModelElement(); model.deleteInternalEvent(imevent); ... }
Figure 14.10. Deleting an internal event type at runtime