So i think i have discovered something, either a limitation of jadex or an extension of my ignorance. I tried creating multiple GoalParameters in a goal and then extracting those parameters in a triggered plan, jadex seems to only take the first GoalParameter and ignore the rest. I have tested this by modifying the tutorial D5 of the BDIv3 Tutorial set. The source code is placed below.
I extended the Translate goal to have two String parameters :
eword --> the english word to translate
lang --> the language that the english word should be translated into
The triggered plan (TranslateToGermanPlan) takes these parameters into its constructor and stores them locally as class fields. The PlanPrecondition then makes sure that the lang Goal Parameter is "german". The output of this agent when the Goal is triggered is as follows:
Using stored platform password: b5b6e1fb-e8d
LMxxxxx9_fc5 platform startup time: 2351 ms.
Commencing Agent Body
Creating Translate to german plan
eword value: bugger
lang value: bugger
Checking language
as you can see the eword and lang have both been set to "bugger" which is the eword value. My original assumption was that if the variable names were the same (ie. "eword" and "lang") in both goal and plan, jadex would map them accordingly. Have I done something wrong or is this a limitation of @GoalParameter annotation
@Agent
@Description("A Translation Agent A1. Implments a top-level goal.")
public class TranslationBDI {
@AgentFeatureIBDIAgentFeaturebdiFeature;@AgentFeatureIExecutionFeatureexecFeature;@BeliefMap<String,String>wordtable=newHashMap<String,String>();@AgentCreatedpublicvoidinit(){wordtable.put("coffee","Kaffee");wordtable.put("milk","Milch");wordtable.put("cow","Kuh");wordtable.put("cat","Katze");wordtable.put("dog","Hund");}//InnerClassGoal@GoalpublicclassTranslate{@GoalParameterprotectedStringeword;@GoalParameterprotectedStringlang;@GoalResultprotectedStringgword;publicTranslate(Stringeword,Stringlang){this.eword=eword;this.lang=lang;}}@Plan(trigger=@Trigger(goals=Translate.class))publicclassTranslateToGermanPlan{protectedStringeword;protectedStringlang;@PlanPreconditionpublicbooleanchecklangGerman(){System.out.println("Checking language");returnthis.lang.equals("german");}publicTranslateToGermanPlan(Stringeword,Stringlang){System.out.println("Creating Translate to german plan");System.out.println("eword value: "+eword);System.out.println("lang value: "+lang);this.eword=eword;this.lang=lang;}@PlanBodypublicvoidbody(){Stringret=wordtable.get(eword);}}@AgentBodypublicvoidbody(){System.out.println("Commencing Agent Body");execFeature.waitForDelay(3000,newIComponentStep<Void>(){@OverridepublicIFuture<Void>execute(IInternalAccessia){System.out.println("Three seconds have past.");System.out.println("Adding word bugger to wordtable");wordtable.put("bugger","Flegel");returnIFuture.DONE;}});Stringeword="bugger";Stringgword=(String)bdiFeature.dispatchTopLevelGoal(newTranslate(eword,"german")).get();System.out.println("Translate: "+eword+" "+gword);}
}
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
the problem is that using only a java constructor for injecting different kinds of values is difficult, because in Java the parameter names are not preserved in the class file. This means we do not have access to "eword" and "lang" during the injection phase. Hence we can only do type matching which is a best effort approach.
public TranslateToGermanPlan(String eword, String lang){
Our solution here is that you can just inject the pojo goal itself using the following code instead
public TranslateToGermanPlan(Translate goal){
From the goal you can access its parameters in the usual Java way.
Best
Lars
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello!
So i think i have discovered something, either a limitation of jadex or an extension of my ignorance. I tried creating multiple GoalParameters in a goal and then extracting those parameters in a triggered plan, jadex seems to only take the first GoalParameter and ignore the rest. I have tested this by modifying the tutorial D5 of the BDIv3 Tutorial set. The source code is placed below.
I extended the Translate goal to have two String parameters :
The triggered plan (TranslateToGermanPlan) takes these parameters into its constructor and stores them locally as class fields. The PlanPrecondition then makes sure that the lang Goal Parameter is "german". The output of this agent when the Goal is triggered is as follows:
Using stored platform password: b5b6e1fb-e8d
LMxxxxx9_fc5 platform startup time: 2351 ms.
Commencing Agent Body
Creating Translate to german plan
eword value: bugger
lang value: bugger
Checking language
as you can see the eword and lang have both been set to "bugger" which is the eword value. My original assumption was that if the variable names were the same (ie. "eword" and "lang") in both goal and plan, jadex would map them accordingly. Have I done something wrong or is this a limitation of @GoalParameter annotation
==================== source code======================
@Agent
@Description("A Translation Agent A1.
Implments a top-level goal.")
public class TranslationBDI {
}
Hi Steve,
the problem is that using only a java constructor for injecting different kinds of values is difficult, because in Java the parameter names are not preserved in the class file. This means we do not have access to "eword" and "lang" during the injection phase. Hence we can only do type matching which is a best effort approach.
public TranslateToGermanPlan(String eword, String lang){
Our solution here is that you can just inject the pojo goal itself using the following code instead
public TranslateToGermanPlan(Translate goal){
From the goal you can access its parameters in the usual Java way.
Best
Lars
Hi Lars,
Thank you for the reply. I see the problem, it makes sense. It doesnt seem a big problem to obtain values from teh goal itself :)
Kind regards