From 4320b67dc44cc6b1fead823f7aca83f9adbb163f Mon Sep 17 00:00:00 2001 From: Andre Paraense Date: Thu, 28 May 2020 19:34:07 +0100 Subject: [PATCH 01/89] Updating CST version --- README.md | 4 ++-- build.gradle | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4b6b9b2..df1c746 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Note: This library is still under development, and some concepts or features mig ``` dependencies { ... - implementation 'com.github.CST-Group:meca:0.2.1' + implementation 'com.github.CST-Group:meca:0.3.0' } ``` @@ -53,7 +53,7 @@ Sometimes, the version number (tag) in this README gets out of date, as maintain com.github.CST-Group meca - 0.2.1 + 0.3.0 ``` diff --git a/build.gradle b/build.gradle index 9f022ed..809af14 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ description = "The Multipurpose Enhanced Cognitive Architecture (MECA)" sourceCompatibility = 1.8 targetCompatibility = 1.8 -version = '0.2.1' +version = '0.3.0' repositories { mavenCentral() @@ -27,7 +27,7 @@ repositories { } dependencies { - api 'com.github.CST-Group:cst:0.3.1' + api 'com.github.CST-Group:cst:1c74737' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' testImplementation 'org.ros.rosjava_messages:rosjava_test_msgs:0.3.0' From 08fc8a605f906ea2b01e75f18514bf72c0f8e3bc Mon Sep 17 00:00:00 2001 From: Andre Paraense Date: Fri, 29 May 2020 18:37:53 +0100 Subject: [PATCH 02/89] CST update --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 809af14..ead1532 100644 --- a/build.gradle +++ b/build.gradle @@ -27,7 +27,7 @@ repositories { } dependencies { - api 'com.github.CST-Group:cst:1c74737' + api 'com.github.CST-Group:cst:0f94e6c' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' testImplementation 'org.ros.rosjava_messages:rosjava_test_msgs:0.3.0' From 93d9d9c604bf134936a8429b4184ab032f62d424 Mon Sep 17 00:00:00 2001 From: Andre Paraense Date: Sat, 4 Jul 2020 11:45:25 +0100 Subject: [PATCH 03/89] Reviewing action sequence plan request strategy for bugs --- .../meca/system1/codelets/BehaviorCodelet.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/br/unicamp/meca/system1/codelets/BehaviorCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/BehaviorCodelet.java index 366337a..7c053d1 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/BehaviorCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/BehaviorCodelet.java @@ -53,7 +53,8 @@ public abstract class BehaviorCodelet extends Codelet { protected Memory actionSequencePlanMemoryContainer; - protected Memory actionSequencePlanRequestMemoryContainer; + //TODO - Review this request action sequence plan strategy +// protected Memory actionSequencePlanRequestMemoryContainer; /** * Creates a MECA Motivational Behavioral Codelet. @@ -136,8 +137,9 @@ public void accessMemoryObjects() { if(actionSequencePlanMemoryContainer == null) actionSequencePlanMemoryContainer = this.getOutput(MecaMind.ACTION_SEQUENCE_PLAN_ID, index); - if(actionSequencePlanRequestMemoryContainer == null) - actionSequencePlanRequestMemoryContainer = this.getOutput(MecaMind.ACTION_SEQUENCE_PLAN_REQUEST_ID, index); + //TODO - Review this request action sequence plan strategy +// if(actionSequencePlanRequestMemoryContainer == null) +// actionSequencePlanRequestMemoryContainer = this.getOutput(MecaMind.ACTION_SEQUENCE_PLAN_REQUEST_ID, index); } @@ -179,10 +181,12 @@ public void proc() { if(actionSequencePlan != null) { ((MemoryContainer) actionSequencePlanMemoryContainer).setI(actionSequencePlan,getActivation(),id); - ((MemoryContainer) actionSequencePlanRequestMemoryContainer).setI(null,0.0d,id); + //TODO - Review this request action sequence plan strategy +// ((MemoryContainer) actionSequencePlanRequestMemoryContainer).setI(null,0.0d,id); }else { ((MemoryContainer) actionSequencePlanMemoryContainer).setI(null,0.0d,id); - ((MemoryContainer) actionSequencePlanRequestMemoryContainer).setI(id,getActivation(),id); + //TODO - Review this request action sequence plan strategy +// ((MemoryContainer) actionSequencePlanRequestMemoryContainer).setI(id,getActivation(),id); } } From 2fc6d36d6317320dccd29c2040e785a6bfb998ce Mon Sep 17 00:00:00 2001 From: Andre Paraense Date: Tue, 7 Jul 2020 20:18:25 +0100 Subject: [PATCH 04/89] Update CST version that solves bug in RosServiceCodelet binding --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index ead1532..ee5966d 100644 --- a/build.gradle +++ b/build.gradle @@ -27,7 +27,7 @@ repositories { } dependencies { - api 'com.github.CST-Group:cst:0f94e6c' + api 'com.github.CST-Group:cst:e439b3c' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' testImplementation 'org.ros.rosjava_messages:rosjava_test_msgs:0.3.0' From fa1032545247056b8ffcf3fb79a26c0b0dcb3b1f Mon Sep 17 00:00:00 2001 From: Andre Paraense Date: Sun, 12 Jul 2020 20:09:53 +0100 Subject: [PATCH 05/89] CST lib update with ability to call or not the ROS service based on the return of the formatRequest method --- build.gradle | 2 +- .../rosservice/AddTwoIntServiceClient.java | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index ee5966d..55ff352 100644 --- a/build.gradle +++ b/build.gradle @@ -27,7 +27,7 @@ repositories { } dependencies { - api 'com.github.CST-Group:cst:e439b3c' + api 'com.github.CST-Group:cst:40cbb53' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' testImplementation 'org.ros.rosjava_messages:rosjava_test_msgs:0.3.0' diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntServiceClient.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntServiceClient.java index f87cc34..732457e 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntServiceClient.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntServiceClient.java @@ -23,12 +23,16 @@ public AddTwoIntServiceClient(String host, URI masterURI) { } @Override - public void formatServiceRequest(Memory motorMemory, AddTwoIntsRequest serviceMessageRequest) { - if(motorMemory != null && motorMemory.getI() != null) { - Integer[] numsToSum = (Integer[]) motorMemory.getI(); - serviceMessageRequest.setA(numsToSum[0]); - serviceMessageRequest.setB(numsToSum[1]); + public boolean formatServiceRequest(Memory motorMemory, AddTwoIntsRequest serviceMessageRequest) { + if(motorMemory == null || motorMemory.getI() == null) { + return false; } + + Integer[] numsToSum = (Integer[]) motorMemory.getI(); + serviceMessageRequest.setA(numsToSum[0]); + serviceMessageRequest.setB(numsToSum[1]); + + return true; } @Override From 1f43279435637d754767c45f2babb6ed9b7ab4fe Mon Sep 17 00:00:00 2001 From: Andre Paraense Date: Mon, 13 Jul 2020 18:21:03 +0100 Subject: [PATCH 06/89] CST lib update: Re-starting RosServiceClientCodelet only after complete shutdown --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 55ff352..24acd5a 100644 --- a/build.gradle +++ b/build.gradle @@ -27,7 +27,7 @@ repositories { } dependencies { - api 'com.github.CST-Group:cst:40cbb53' + api 'com.github.CST-Group:cst:8675e7e' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' testImplementation 'org.ros.rosjava_messages:rosjava_test_msgs:0.3.0' From 19ad449185b0f5521604653cee3a9909e4b07d8c Mon Sep 17 00:00:00 2001 From: Andre Paraense Date: Thu, 23 Jul 2020 18:41:35 +0100 Subject: [PATCH 07/89] CST lib update - RosServiceClientCodelet implemented as a one run with semaphore control --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 24acd5a..58f0d52 100644 --- a/build.gradle +++ b/build.gradle @@ -27,7 +27,7 @@ repositories { } dependencies { - api 'com.github.CST-Group:cst:8675e7e' + api 'com.github.CST-Group:cst:7a7ebd5' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' testImplementation 'org.ros.rosjava_messages:rosjava_test_msgs:0.3.0' From b91edac2a7d4512e0d06680ab188fe2e09034627 Mon Sep 17 00:00:00 2001 From: Andre Paraense Date: Sat, 25 Jul 2020 15:02:49 +0100 Subject: [PATCH 08/89] CST update - RosServiceSnc able to reuse --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 58f0d52..6df433c 100644 --- a/build.gradle +++ b/build.gradle @@ -27,7 +27,7 @@ repositories { } dependencies { - api 'com.github.CST-Group:cst:7a7ebd5' + api 'com.github.CST-Group:cst:24454f6' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' testImplementation 'org.ros.rosjava_messages:rosjava_test_msgs:0.3.0' From 1b4eb552ba3a53a4a751c586a79526e8cbac9651 Mon Sep 17 00:00:00 2001 From: Andre Paraense Date: Sat, 25 Jul 2020 16:24:39 +0100 Subject: [PATCH 09/89] CST lib update --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 6df433c..a9bb8a3 100644 --- a/build.gradle +++ b/build.gradle @@ -27,7 +27,7 @@ repositories { } dependencies { - api 'com.github.CST-Group:cst:24454f6' + api 'com.github.CST-Group:cst:0.4.0' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' testImplementation 'org.ros.rosjava_messages:rosjava_test_msgs:0.3.0' From 78a00d3db6276bac89f7b2c7a786e7ed04c65ba7 Mon Sep 17 00:00:00 2001 From: Andre Paraense Date: Sat, 25 Jul 2020 16:32:04 +0100 Subject: [PATCH 10/89] Removing TODOs --- .../meca/system1/codelets/BehaviorCodelet.java | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/main/java/br/unicamp/meca/system1/codelets/BehaviorCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/BehaviorCodelet.java index 7c053d1..366337a 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/BehaviorCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/BehaviorCodelet.java @@ -53,8 +53,7 @@ public abstract class BehaviorCodelet extends Codelet { protected Memory actionSequencePlanMemoryContainer; - //TODO - Review this request action sequence plan strategy -// protected Memory actionSequencePlanRequestMemoryContainer; + protected Memory actionSequencePlanRequestMemoryContainer; /** * Creates a MECA Motivational Behavioral Codelet. @@ -137,9 +136,8 @@ public void accessMemoryObjects() { if(actionSequencePlanMemoryContainer == null) actionSequencePlanMemoryContainer = this.getOutput(MecaMind.ACTION_SEQUENCE_PLAN_ID, index); - //TODO - Review this request action sequence plan strategy -// if(actionSequencePlanRequestMemoryContainer == null) -// actionSequencePlanRequestMemoryContainer = this.getOutput(MecaMind.ACTION_SEQUENCE_PLAN_REQUEST_ID, index); + if(actionSequencePlanRequestMemoryContainer == null) + actionSequencePlanRequestMemoryContainer = this.getOutput(MecaMind.ACTION_SEQUENCE_PLAN_REQUEST_ID, index); } @@ -181,12 +179,10 @@ public void proc() { if(actionSequencePlan != null) { ((MemoryContainer) actionSequencePlanMemoryContainer).setI(actionSequencePlan,getActivation(),id); - //TODO - Review this request action sequence plan strategy -// ((MemoryContainer) actionSequencePlanRequestMemoryContainer).setI(null,0.0d,id); + ((MemoryContainer) actionSequencePlanRequestMemoryContainer).setI(null,0.0d,id); }else { ((MemoryContainer) actionSequencePlanMemoryContainer).setI(null,0.0d,id); - //TODO - Review this request action sequence plan strategy -// ((MemoryContainer) actionSequencePlanRequestMemoryContainer).setI(id,getActivation(),id); + ((MemoryContainer) actionSequencePlanRequestMemoryContainer).setI(id,getActivation(),id); } } From 783ec8684dcc0961902175c9e6624ba42d3ce241 Mon Sep 17 00:00:00 2001 From: Ricardo Gudwin Date: Wed, 5 Aug 2020 10:19:33 -0300 Subject: [PATCH 11/89] Adaptations to changes in CST 0.5.0 --- build.gradle | 31 +- .../java/br/unicamp/meca/mind/MecaMind.java | 1614 ++++++++--------- .../meca/models/ActionSequencePlan.java | 2 +- .../br/unicamp/meca/models/ActionStep.java | 43 + 4 files changed, 837 insertions(+), 853 deletions(-) create mode 100644 src/main/java/br/unicamp/meca/models/ActionStep.java diff --git a/build.gradle b/build.gradle index 24acd5a..43bad48 100644 --- a/build.gradle +++ b/build.gradle @@ -13,6 +13,9 @@ targetCompatibility = 1.8 version = '0.3.0' repositories { + flatDir { + dirs '../cst/build/libs' + } mavenCentral() maven { url 'https://jitpack.io' } maven { @@ -27,12 +30,21 @@ repositories { } dependencies { - api 'com.github.CST-Group:cst:8675e7e' + //api 'com.github.CST-Group:cst:0.5.0' + api ':cst:0.5.0-full' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' testImplementation 'org.ros.rosjava_messages:rosjava_test_msgs:0.3.0' } +jar { + manifest { + attributes( + 'Class-Path': configurations.runtimeClasspath.files.collect { it.getName() }.join(' ') + ) + } +} + task javadocJar(type: Jar) { classifier = 'javadoc' from javadoc @@ -41,9 +53,24 @@ task sourcesJar(type: Jar) { classifier = 'sources' from sourceSets.main.allSource } +task uberJar(type: Jar) { + archiveClassifier = 'full' + manifest { + attributes( +// 'Class-Path': configurations.compile.collect { it.getName() }.join(' '), + 'Class-Path': configurations.runtimeClasspath.files.collect { it.getName() }.join(' ') + ) + + } + from sourceSets.main.output + dependsOn configurations.runtimeClasspath + from { + configurations.runtimeClasspath.findAll { it.name.endsWith('jar') }.collect { zipTree(it) } + } +} artifacts { - archives javadocJar, sourcesJar + archives javadocJar, sourcesJar, uberJar } jacocoTestReport { diff --git a/src/main/java/br/unicamp/meca/mind/MecaMind.java b/src/main/java/br/unicamp/meca/mind/MecaMind.java index bead176..c337b12 100644 --- a/src/main/java/br/unicamp/meca/mind/MecaMind.java +++ b/src/main/java/br/unicamp/meca/mind/MecaMind.java @@ -53,881 +53,795 @@ */ public class MecaMind extends Mind { - public static final String ACTION_SEQUENCE_PLAN_ID = "ACTION_SEQUENCE_PLAN_ID"; - - public static final String ACTION_SEQUENCE_PLAN_REQUEST_ID = "ACTION_SEQUENCE_PLAN_REQUEST_ID"; - - /* - * System 1 - */ - - private List sensoryCodelets; - - private List perceptualCodelets; - - private List moodCodelets; - - private List motivationalCodelets; - - private AttentionCodelet attentionCodeletSystem1; - - private List emotionalCodelets; - - private List actionFromPlanningCodelets; - - private List actionFromPerceptionCodelets; - - private List behaviorCodelets; - - private List motorCodelets; - - private Memory actionSequencePlanMemoryContainer; - - private Memory actionSequencePlanRequestMemoryContainer; - /* - * System 2 - */ - - private List attentionCodeletsSystem2; - - private EpisodicLearningCodelet episodicLearningCodelet; - - private EpisodicRetrievalCodelet episodicRetrievalCodelet; - - private ExpectationCodelet expectationCodelet; - - private ConsciousnessCodelet consciousnessCodelet; - - private SoarCodelet soarCodelet; - - private GoalCodelet goalCodelet; - - private AppraisalCodelet appraisalCodelet; - - private WorkingMemory workingMemory; - - private String id; - - /** - * Creates the MECA Mind. - */ - public MecaMind() { - setId(UUID.randomUUID().toString()); - setWorkingMemory(new WorkingMemory(getId())); - } - - /** - * Creates the MECA Mind. - * - * @param id - * the id of the MECA mind. Must be unique per MECA mind. - */ - public MecaMind(String id) { - setId(id); - setWorkingMemory(new WorkingMemory(getId())); - } - - /** - * Mounts the MECA Mind. After creating the MECA Mind's instance and setting - * all the codelets inside it, this method is responsible for binding - * together all codelets inside the mind, creating memories (objects and - * containers) and setting them either as inputs or outputs of each codelet, - * according to MECA's reference architecture. - *

- * This method must be called before running the MECA Agent. - */ - public void mountMecaMind() { - - mountSensoryCodelets(); - - mountPerceptualCodelets(); - - mountMotorCodelets(); - - mountAttentionCodelets(); - - mountWorkingMemory(); - - mountSoarCodelet(); - - mountMotivationalCodelets(); - - mountActionSequencePlanMemory(); - - mountBehaviorCodelets(); - - mountActionFromPlanningCodelets(); - - mountActionFromPerceptionCodelets(); - - mountModules(); - - } - - private void mountActionSequencePlanMemory() { - - actionSequencePlanMemoryContainer = createMemoryContainer(ACTION_SEQUENCE_PLAN_ID); - - actionSequencePlanRequestMemoryContainer = createMemoryContainer(ACTION_SEQUENCE_PLAN_REQUEST_ID); - - } - - private void mountModules() { - - if (getMotivationalCodelets() != null) { - if (getMotivationalCodelets().size() > 0) { - List mtcodelets = getMotivationalCodelets(); - getMotivationalSubsystemModule() - .setMotivationalCodelets((List) mtcodelets); - } - - } - - if (getSoarCodelet() != null) { - getPlansSubsystemModule().setjSoarCodelet(getSoarCodelet()); - } - - } - - private void mountPerceptualCodelets() { - if (perceptualCodelets != null) { - for (PerceptualCodelet perceptualCodelet : perceptualCodelets) { - if (perceptualCodelet != null && perceptualCodelet.getId() != null) { - - insertCodelet(perceptualCodelet); - /* - * Inputs - */ - if (sensoryCodelets != null) { - for (ISensoryCodelet sensoryCodelet : sensoryCodelets) { - if (sensoryCodelet != null && sensoryCodelet.getId() != null) { - ArrayList sensoryCodeletsIds = perceptualCodelet.getSensoryCodeletsIds(); - if (sensoryCodeletsIds != null) { - for (String sensoryCodeletId : sensoryCodeletsIds) { - if (sensoryCodeletId != null - && sensoryCodeletId.equalsIgnoreCase(sensoryCodelet.getId())) { - perceptualCodelet.addInputs(sensoryCodelet.getOutputs()); - } - } - } - } - } + public static final String ACTION_SEQUENCE_PLAN_ID = "ACTION_SEQUENCE_PLAN_ID"; + public static final String ACTION_SEQUENCE_PLAN_REQUEST_ID = "ACTION_SEQUENCE_PLAN_REQUEST_ID"; + + /* + * System 1 + */ + + private List sensoryCodelets; + private List perceptualCodelets; + private List moodCodelets; + private List motivationalCodelets; + private AttentionCodelet attentionCodeletSystem1; + private List emotionalCodelets; + private List actionFromPlanningCodelets; + private List actionFromPerceptionCodelets; + private List behaviorCodelets; + private List motorCodelets; + private Memory actionSequencePlanMemoryContainer; + private Memory actionSequencePlanRequestMemoryContainer; + + /* + * System 2 + */ + + private List attentionCodeletsSystem2; + private EpisodicLearningCodelet episodicLearningCodelet; + private EpisodicRetrievalCodelet episodicRetrievalCodelet; + private ExpectationCodelet expectationCodelet; + private ConsciousnessCodelet consciousnessCodelet; + private SoarCodelet soarCodelet; + private GoalCodelet goalCodelet; + private AppraisalCodelet appraisalCodelet; + private WorkingMemory workingMemory; + + private String id; + + /** + * Creates the MECA Mind. + */ + public MecaMind() { + setId(UUID.randomUUID().toString()); + setWorkingMemory(new WorkingMemory(getId())); + } + + /** + * Creates the MECA Mind. + * + * @param id + * the id of the MECA mind. Must be unique per MECA mind. + */ + public MecaMind(String id) { + setId(id); + setWorkingMemory(new WorkingMemory(getId())); + } + + /** + * Mounts the MECA Mind. After creating the MECA Mind's instance and setting + * all the codelets inside it, this method is responsible for binding + * together all codelets inside the mind, creating memories (objects and + * containers) and setting them either as inputs or outputs of each codelet, + * according to MECA's reference architecture. + *

+ * This method must be called before running the MECA Agent. + */ + public void mountMecaMind() { + mountSensoryCodelets(); + mountPerceptualCodelets(); + mountMotorCodelets(); + mountAttentionCodelets(); + mountWorkingMemory(); + mountSoarCodelet(); + mountMotivationalCodelets(); + mountActionSequencePlanMemory(); + mountBehaviorCodelets(); + mountActionFromPlanningCodelets(); + mountActionFromPerceptionCodelets(); + mountModules(); + } + + private void mountActionSequencePlanMemory() { + actionSequencePlanMemoryContainer = createMemoryContainer(ACTION_SEQUENCE_PLAN_ID); + actionSequencePlanRequestMemoryContainer = createMemoryContainer(ACTION_SEQUENCE_PLAN_REQUEST_ID); + } + + private void mountModules() { +// if (getMotivationalCodelets() != null) { +// if (getMotivationalCodelets().size() > 0) { +// List mtcodelets = getMotivationalCodelets(); +//// getMotivationalSubsystemModule() +//// .setMotivationalCodelets((List) mtcodelets); +// } +// } + if (getSoarCodelet() != null) { + getPlansSubsystemModule().setjSoarCodelet(getSoarCodelet()); + } + } + + private void mountPerceptualCodelets() { + if (perceptualCodelets != null) { + for (PerceptualCodelet perceptualCodelet : perceptualCodelets) { + if (perceptualCodelet != null && perceptualCodelet.getId() != null) { + insertCodelet(perceptualCodelet); + /* + * Inputs + */ + if (sensoryCodelets != null) { + for (ISensoryCodelet sensoryCodelet : sensoryCodelets) { + if (sensoryCodelet != null && sensoryCodelet.getId() != null) { + ArrayList sensoryCodeletsIds = perceptualCodelet.getSensoryCodeletsIds(); + if (sensoryCodeletsIds != null) { + for (String sensoryCodeletId : sensoryCodeletsIds) { + if (sensoryCodeletId != null && sensoryCodeletId.equalsIgnoreCase(sensoryCodelet.getId())) { + perceptualCodelet.addInputs(sensoryCodelet.getOutputs()); } - /* - * Output - */ - MemoryObject perceptualMemory = createMemoryObject(perceptualCodelet.getId()); - perceptualCodelet.addOutput(perceptualMemory); - + } } + } } + } + /* + * Output + */ + MemoryObject perceptualMemory = createMemoryObject(perceptualCodelet.getId()); + perceptualCodelet.addOutput(perceptualMemory); } - } - - private void mountSensoryCodelets() { - if (sensoryCodelets != null) { - - for (ISensoryCodelet sensoryCodelet : sensoryCodelets) { - if (sensoryCodelet != null && sensoryCodelet.getId() != null) { - - insertCodelet((Codelet) sensoryCodelet); - /* - * Output - */ - MemoryObject sensoryMemory = createMemoryObject(sensoryCodelet.getId()); - sensoryCodelet.addOutput(sensoryMemory); - - } - } + } + } + } + + private void mountSensoryCodelets() { + if (sensoryCodelets != null) { + for (ISensoryCodelet sensoryCodelet : sensoryCodelets) { + if (sensoryCodelet != null && sensoryCodelet.getId() != null) { + insertCodelet((Codelet) sensoryCodelet); + /* + * Output + */ + MemoryObject sensoryMemory = createMemoryObject(sensoryCodelet.getId()); + sensoryCodelet.addOutput(sensoryMemory); } - } - - private void mountMotivationalCodelets() { - if (getMotivationalCodelets() != null) { - for (MotivationalCodelet motivationalCodelet : getMotivationalCodelets()) { - - /* - * Input Sensors - */ - if (motivationalCodelet.getSensoryCodeletsIds() != null) { - List sensoryIds = motivationalCodelet.getSensoryCodeletsIds(); - for (String sensoryId : sensoryIds) { - if (sensoryCodelets != null) { - for (ISensoryCodelet sensoryCodelet : sensoryCodelets) { - if (sensoryCodelet.getId().equals(sensoryId)) { - motivationalCodelet.addInputs(sensoryCodelet.getOutputs()); - - } - } - } - } + } + } + } + + private void mountMotivationalCodelets() { + if (getMotivationalCodelets() != null) { + for (MotivationalCodelet motivationalCodelet : getMotivationalCodelets()) { + /* + * Input Sensors + */ + if (motivationalCodelet.getSensoryCodeletsIds() != null) { + List sensoryIds = motivationalCodelet.getSensoryCodeletsIds(); + for (String sensoryId : sensoryIds) { + if (sensoryCodelets != null) { + for (ISensoryCodelet sensoryCodelet : sensoryCodelets) { + if (sensoryCodelet.getId().equals(sensoryId)) { + motivationalCodelet.addInputs(sensoryCodelet.getOutputs()); } - - /* - * Input Drives - */ - - if (motivationalCodelet.getMotivationalCodeletsIds() != null) { - HashMap motivationalCodeletsIds = motivationalCodelet.getMotivationalCodeletsIds(); - for (Map.Entry motivationalCodeletId : motivationalCodeletsIds.entrySet()) { - - for (MotivationalCodelet motivationalCodeletInput : getMotivationalCodelets()) { - if (motivationalCodeletInput.getId().equals(motivationalCodeletId.getKey())) { - - HashMap driveRelevance = new HashMap<>(); - driveRelevance.put(motivationalCodeletInput.getOutputDriveMO(), - motivationalCodeletId.getValue()); - - motivationalCodelet.addInput(this.createMemoryObject( - motivationalCodeletInput.getOutputDriveMO().getName(), driveRelevance)); - } - } - } - } - - /* - * Output Drives - */ - MemoryObject outputDrive = this.createMemoryObject(motivationalCodelet.getId() + "_DRIVE_MO"); - motivationalCodelet.addOutput(outputDrive); - - insertCodelet(motivationalCodelet); + } } + } } - } - - private void mountBehaviorCodelets() { - if (behaviorCodelets != null) { - for (BehaviorCodelet behaviorCodelet : behaviorCodelets) { - if (behaviorCodelet != null && behaviorCodelet.getId() != null - && behaviorCodelet.getMotivationalCodeletsIds() != null - && behaviorCodelet.getPerceptualCodeletsIds() != null) { - - /* - * Outputs - */ - behaviorCodelet.addOutput(actionSequencePlanMemoryContainer); - behaviorCodelet.addOutput(actionSequencePlanRequestMemoryContainer); - - /* - * Inputs - */ - if (motivationalCodelets != null) { - for (MotivationalCodelet motivationalCodelet : motivationalCodelets) { - if (motivationalCodelet != null && motivationalCodelet.getId() != null) { - ArrayList motivationalCodeletsIds = behaviorCodelet - .getMotivationalCodeletsIds(); - if (motivationalCodeletsIds != null) { - for (String motivationalCodeletId : motivationalCodeletsIds) { - if (motivationalCodeletId != null && motivationalCodelet.getId() - .equalsIgnoreCase(motivationalCodeletId)) { - behaviorCodelet.addInputs(motivationalCodelet.getOutputs()); - } - } - } - } - } - } - - if(perceptualCodelets != null) { - for(PerceptualCodelet perceptualCodelet : perceptualCodelets) { - if(perceptualCodelet != null && perceptualCodelet.getId() != null) { - ArrayList perceptualCodeletsIds = behaviorCodelet.getPerceptualCodeletsIds(); - if(perceptualCodeletsIds != null) { - for(String perceptualCodeletId : perceptualCodeletsIds) { - if(perceptualCodeletId != null && perceptualCodelet.getId().equalsIgnoreCase(perceptualCodeletId)) { - behaviorCodelet.addInputs(perceptualCodelet.getOutputs()); - } - } - } - } - } - } - - if (soarCodelet != null && soarCodelet.getId() != null && behaviorCodelet.getSoarCodeletId() != null) { - if (soarCodelet.getId().equalsIgnoreCase(behaviorCodelet.getSoarCodeletId())) { - behaviorCodelet.addBroadcasts(soarCodelet.getOutputs()); - } - - } - - insertCodelet(behaviorCodelet); - - } + /* + * Input Drives + */ + if (motivationalCodelet.getMotivationalCodeletsIds() != null) { + HashMap motivationalCodeletsIds = motivationalCodelet.getMotivationalCodeletsIds(); + for (Map.Entry motivationalCodeletId : motivationalCodeletsIds.entrySet()) { + for (MotivationalCodelet motivationalCodeletInput : getMotivationalCodelets()) { + if (motivationalCodeletInput.getId().equals(motivationalCodeletId.getKey())) { + HashMap driveRelevance = new HashMap<>(); + driveRelevance.put(motivationalCodeletInput.getOutputDriveMO(), + motivationalCodeletId.getValue()); + motivationalCodelet.addInput(this.createMemoryObject( + motivationalCodeletInput.getOutputDriveMO().getName(), driveRelevance)); + } } + } } - } - - private void mountActionFromPerceptionCodelets() { - if (actionFromPerceptionCodelets != null) { - for (ActionFromPerceptionCodelet actionCodelet : actionFromPerceptionCodelets) { - if (actionCodelet != null && actionCodelet.getId() != null - && actionCodelet.getPerceptualCodeletsIds() != null - && actionCodelet.getMotivationalCodeletsIds() != null - && actionCodelet.getMotorCodeletId() != null) { - - insertCodelet(actionCodelet); - /* - * Outputs - */ - if (motorCodelets != null) { - for (IMotorCodelet motorCodelet : motorCodelets) { - if (motorCodelet != null && motorCodelet.getId() != null) { - if (motorCodelet.getId() - .equalsIgnoreCase(actionCodelet.getMotorCodeletId())) { - actionCodelet.addOutputs(motorCodelet.getInputs()); - } - } - } - } - /* - * Inputs - */ - - if (motivationalCodelets != null) { - for (MotivationalCodelet motivationalCodelet : motivationalCodelets) { - if (motivationalCodelet != null && motivationalCodelet.getId() != null) { - ArrayList motivationalCodeletsIds = actionCodelet - .getMotivationalCodeletsIds(); - if (motivationalCodeletsIds != null) { - for (String motivationalCodeletId : motivationalCodeletsIds) { - if (motivationalCodeletId != null && motivationalCodelet.getId() - .equalsIgnoreCase(motivationalCodeletId)) { - actionCodelet.addInputs(motivationalCodelet.getOutputs()); - } - } - } - } - } - } - - if (perceptualCodelets != null) { - for (PerceptualCodelet perceptualCodelet : perceptualCodelets) { - if (perceptualCodelet != null && perceptualCodelet.getId() != null) { - ArrayList perceptualCodeletsIds = actionCodelet - .getPerceptualCodeletsIds(); - if (perceptualCodeletsIds != null) { - for (String perceptualCodeletId : perceptualCodeletsIds) { - if (perceptualCodeletId != null - && perceptualCodelet.getId().equalsIgnoreCase(perceptualCodeletId)) { - actionCodelet.addInputs(perceptualCodelet.getOutputs()); - } - } - } - } - } + /* + * Output Drives + */ + MemoryObject outputDrive = this.createMemoryObject(motivationalCodelet.getId() + "_DRIVE_MO"); + motivationalCodelet.addOutput(outputDrive); + insertCodelet(motivationalCodelet); + } + } + } + + private void mountBehaviorCodelets() { + if (behaviorCodelets != null) { + for (BehaviorCodelet behaviorCodelet : behaviorCodelets) { + if (behaviorCodelet != null && behaviorCodelet.getId() != null + && behaviorCodelet.getMotivationalCodeletsIds() != null + && behaviorCodelet.getPerceptualCodeletsIds() != null) { + /* + * Outputs + */ + behaviorCodelet.addOutput(actionSequencePlanMemoryContainer); + behaviorCodelet.addOutput(actionSequencePlanRequestMemoryContainer); + /* + * Inputs + */ + if (motivationalCodelets != null) { + for (MotivationalCodelet motivationalCodelet : motivationalCodelets) { + if (motivationalCodelet != null && motivationalCodelet.getId() != null) { + ArrayList motivationalCodeletsIds = behaviorCodelet.getMotivationalCodeletsIds(); + if (motivationalCodeletsIds != null) { + for (String motivationalCodeletId : motivationalCodeletsIds) { + if (motivationalCodeletId != null && motivationalCodelet.getId().equalsIgnoreCase(motivationalCodeletId)) { + behaviorCodelet.addInputs(motivationalCodelet.getOutputs()); + } + } + } + } + } + } + if(perceptualCodelets != null) { + for(PerceptualCodelet perceptualCodelet : perceptualCodelets) { + if(perceptualCodelet != null && perceptualCodelet.getId() != null) { + ArrayList perceptualCodeletsIds = behaviorCodelet.getPerceptualCodeletsIds(); + if(perceptualCodeletsIds != null) { + for(String perceptualCodeletId : perceptualCodeletsIds) { + if(perceptualCodeletId != null && perceptualCodelet.getId().equalsIgnoreCase(perceptualCodeletId)) { + behaviorCodelet.addInputs(perceptualCodelet.getOutputs()); + } + } + } + } + } + } + if (soarCodelet != null && soarCodelet.getId() != null && behaviorCodelet.getSoarCodeletId() != null) { + if (soarCodelet.getId().equalsIgnoreCase(behaviorCodelet.getSoarCodeletId())) { + behaviorCodelet.addBroadcasts(soarCodelet.getOutputs()); + } + } + insertCodelet(behaviorCodelet); + } + } + } + } + + private void mountActionFromPerceptionCodelets() { + if (actionFromPerceptionCodelets != null) { + for (ActionFromPerceptionCodelet actionCodelet : actionFromPerceptionCodelets) { + if (actionCodelet != null && actionCodelet.getId() != null + && actionCodelet.getPerceptualCodeletsIds() != null + && actionCodelet.getMotivationalCodeletsIds() != null + && actionCodelet.getMotorCodeletId() != null) { + insertCodelet(actionCodelet); + /* + * Outputs + */ + if (motorCodelets != null) { + for (IMotorCodelet motorCodelet : motorCodelets) { + if (motorCodelet != null && motorCodelet.getId() != null) { + if (motorCodelet.getId().equalsIgnoreCase(actionCodelet.getMotorCodeletId())) { + actionCodelet.addOutputs(motorCodelet.getInputs()); + } + } + } + } + /* + * Inputs + */ + if (motivationalCodelets != null) { + for (MotivationalCodelet motivationalCodelet : motivationalCodelets) { + if (motivationalCodelet != null && motivationalCodelet.getId() != null) { + ArrayList motivationalCodeletsIds = actionCodelet.getMotivationalCodeletsIds(); + if (motivationalCodeletsIds != null) { + for (String motivationalCodeletId : motivationalCodeletsIds) { + if (motivationalCodeletId != null && motivationalCodelet.getId().equalsIgnoreCase(motivationalCodeletId)) { + actionCodelet.addInputs(motivationalCodelet.getOutputs()); } - - if (soarCodelet != null && soarCodelet.getId() != null && actionCodelet.getSoarCodeletId() != null) { - if (soarCodelet.getId().equalsIgnoreCase(actionCodelet.getSoarCodeletId())) { - actionCodelet.addBroadcasts(soarCodelet.getOutputs()); - } - - } + } } + } } - } - - } - - private void mountActionFromPlanningCodelets() { - if (actionFromPlanningCodelets != null) { - for (ActionFromPlanningCodelet actionCodelet : actionFromPlanningCodelets) { - if (actionCodelet != null && actionCodelet.getId() != null - && actionCodelet.getPerceptualCodeletsIds() != null - && actionCodelet.getMotorCodeletId() != null) { - - insertCodelet(actionCodelet); - /* - * Outputs - */ - if (motorCodelets != null) { - for (IMotorCodelet motorCodelet : motorCodelets) { - if (motorCodelet != null && motorCodelet.getId() != null) { - if (motorCodelet.getId() - .equalsIgnoreCase(actionCodelet.getMotorCodeletId())) { - actionCodelet.addOutputs(motorCodelet.getInputs()); - } - } - } - } - /* - * Inputs - */ - if (perceptualCodelets != null) { - for (PerceptualCodelet perceptualCodelet : perceptualCodelets) { - if (perceptualCodelet != null && perceptualCodelet.getId() != null) { - ArrayList perceptualCodeletsIds = actionCodelet - .getPerceptualCodeletsIds(); - if (perceptualCodeletsIds != null) { - for (String perceptualCodeletId : perceptualCodeletsIds) { - if (perceptualCodeletId != null - && perceptualCodelet.getId().equalsIgnoreCase(perceptualCodeletId)) { - actionCodelet.addInputs(perceptualCodelet.getOutputs()); - } - } - } - } - } - } - - if (soarCodelet != null && soarCodelet.getId() != null && actionCodelet.getSoarCodeletId() != null) { - if (soarCodelet.getId().equalsIgnoreCase(actionCodelet.getSoarCodeletId())) { - actionCodelet.addBroadcasts(soarCodelet.getOutputs()); - } - + } + if (perceptualCodelets != null) { + for (PerceptualCodelet perceptualCodelet : perceptualCodelets) { + if (perceptualCodelet != null && perceptualCodelet.getId() != null) { + ArrayList perceptualCodeletsIds = actionCodelet.getPerceptualCodeletsIds(); + if (perceptualCodeletsIds != null) { + for (String perceptualCodeletId : perceptualCodeletsIds) { + if (perceptualCodeletId != null && perceptualCodelet.getId().equalsIgnoreCase(perceptualCodeletId)) { + actionCodelet.addInputs(perceptualCodelet.getOutputs()); } - - actionCodelet.addInput(actionSequencePlanMemoryContainer); - } + } + } + } + } + } + if (soarCodelet != null && soarCodelet.getId() != null && actionCodelet.getSoarCodeletId() != null) { + if (soarCodelet.getId().equalsIgnoreCase(actionCodelet.getSoarCodeletId())) { + actionCodelet.addBroadcasts(soarCodelet.getOutputs()); } + } } - } - - private void mountMotorCodelets() { - if (motorCodelets != null) { + } + } + } + + private void mountActionFromPlanningCodelets() { + if (actionFromPlanningCodelets != null) { + for (ActionFromPlanningCodelet actionCodelet : actionFromPlanningCodelets) { + if (actionCodelet != null && actionCodelet.getId() != null + && actionCodelet.getPerceptualCodeletsIds() != null + && actionCodelet.getMotorCodeletId() != null) { + insertCodelet(actionCodelet); + /* + * Outputs + */ + if (motorCodelets != null) { for (IMotorCodelet motorCodelet : motorCodelets) { - if (motorCodelet != null && motorCodelet.getId() != null) { - insertCodelet((Codelet) motorCodelet); - /* - * Input - */ - Memory motorMemoryContainer = createMemoryContainer(motorCodelet.getId()); - motorCodelet.addInput(motorMemoryContainer); + if (motorCodelet != null && motorCodelet.getId() != null) { + if (motorCodelet.getId().equalsIgnoreCase(actionCodelet.getMotorCodeletId())) { + actionCodelet.addOutputs(motorCodelet.getInputs()); } + } } - } - } - - private void mountAttentionCodelets() { - if (attentionCodeletSystem1 != null) { - - /* - * Inputs - */ - if (perceptualCodelets != null) { - for (String inputPerceptualId : attentionCodeletSystem1.getPerceptualCodeletsIds()) { - for (PerceptualCodelet perceptualCodelet : perceptualCodelets) { - - if (inputPerceptualId.equals(perceptualCodelet.getId())) { - attentionCodeletSystem1.addInputs(perceptualCodelet.getOutputs()); - } + } + /* + * Inputs + */ + if (perceptualCodelets != null) { + for (PerceptualCodelet perceptualCodelet : perceptualCodelets) { + if (perceptualCodelet != null && perceptualCodelet.getId() != null) { + ArrayList perceptualCodeletsIds = actionCodelet.getPerceptualCodeletsIds(); + if (perceptualCodeletsIds != null) { + for (String perceptualCodeletId : perceptualCodeletsIds) { + if (perceptualCodeletId != null && perceptualCodelet.getId().equalsIgnoreCase(perceptualCodeletId)) { + actionCodelet.addInputs(perceptualCodelet.getOutputs()); + } } + } } + } } - /* - * Outputs - */ - Memory attentionMemoryOutput = createMemoryObject(attentionCodeletSystem1.getId()); - attentionCodeletSystem1.addOutput(attentionMemoryOutput); - attentionCodeletSystem1.setOutputFilteredPerceptsMO(attentionMemoryOutput); - insertCodelet(attentionCodeletSystem1); + if (soarCodelet != null && soarCodelet.getId() != null && actionCodelet.getSoarCodeletId() != null) { + if (soarCodelet.getId().equalsIgnoreCase(actionCodelet.getSoarCodeletId())) { + actionCodelet.addBroadcasts(soarCodelet.getOutputs()); + } + } + actionCodelet.addInput(actionSequencePlanMemoryContainer); } - } - - private void mountSoarCodelet() { - if (soarCodelet != null) { - soarCodelet.addInput(createMemoryObject(WorkingMemory.WORKING_MEMORY_INPUT, getWorkingMemory())); - soarCodelet.addOutput(createMemoryObject(soarCodelet.getId())); - insertCodelet(soarCodelet); + } + } + } + + private void mountMotorCodelets() { + if (motorCodelets != null) { + for (IMotorCodelet motorCodelet : motorCodelets) { + if (motorCodelet != null && motorCodelet.getId() != null) { + insertCodelet((Codelet) motorCodelet); + /* + * Input + */ + Memory motorMemoryContainer = createMemoryContainer(motorCodelet.getId()); + motorCodelet.addInput(motorMemoryContainer); } - - } - - private void mountWorkingMemory() { - if (getWorkingMemory() != null) { - - if (attentionCodeletSystem1 != null) { - getWorkingMemory().setCurrentPerceptionMemory(attentionCodeletSystem1.getOutputFilteredPerceptsMO()); + } + } + } + + private void mountAttentionCodelets() { + if (attentionCodeletSystem1 != null) { + /* + * Inputs + */ + if (perceptualCodelets != null) { + for (String inputPerceptualId : attentionCodeletSystem1.getPerceptualCodeletsIds()) { + for (PerceptualCodelet perceptualCodelet : perceptualCodelets) { + if (inputPerceptualId.equals(perceptualCodelet.getId())) { + attentionCodeletSystem1.addInputs(perceptualCodelet.getOutputs()); } - + } } - } - - /** - * Sets the Sensory Codelets. - * - * @deprecated instead, add Sensory Codelets using the interface ISensoryCodelet - * - * @param sensoryCodelets - * the sensoryCodelets to set - */ - @Deprecated - public void setSensoryCodelets(List sensoryCodelets) { - this.sensoryCodelets = new ArrayList(); - this.sensoryCodelets.addAll(sensoryCodelets); - } - - /** - * Sets the Perceptual Codelets. - * - * @param perceptualCodelets - * the perceptualCodelets to set - */ - public void setPerceptualCodelets(List perceptualCodelets) { - this.perceptualCodelets = perceptualCodelets; - } - - /** - * Sets the Mood Codelets. - * - * @param moodCodelets - * the moodCodelets to set - */ - public void setMoodCodelets(List moodCodelets) { - this.moodCodelets = moodCodelets; - } - - /** - * Sets the Motivational Codelets. - * - * @param motivationalCodelets - * the motivationalCodelets to set - */ - public void setMotivationalCodelets(List motivationalCodelets) { - this.motivationalCodelets = motivationalCodelets; - } - - /** - * Sets the System 1 Attention Codelet. - * - * @param attentionCodeletSystem1 - * the attentionCodeletSystem1 to set - */ - public void setAttentionCodeletSystem1(AttentionCodelet attentionCodeletSystem1) { - this.attentionCodeletSystem1 = attentionCodeletSystem1; - } - - /** - * Sets the Emotional Codelets. - * - * @param emotionalCodelets - * the emotionalCodelets to set - */ - public void setEmotionalCodelets(List emotionalCodelets) { - this.emotionalCodelets = emotionalCodelets; - } - - /** - * Sets the Motor Codelets. - * - * @deprecated instead, add Motor Codelets using the interface IMotorCodelet - * @param motorCodelets - * the motorCodelets to set - */ - @Deprecated - public void setMotorCodelets(List motorCodelets) { - this.motorCodelets = new ArrayList(); - this.motorCodelets.addAll(motorCodelets); - } - - /** - * Sets the System 2 Attention Codelets - * - * @param attentionCodeletsSystem2 - * the attentionCodeletsSystem2 to set - */ - public void setAttentionCodeletsSystem2( - List attentionCodeletsSystem2) { - this.attentionCodeletsSystem2 = attentionCodeletsSystem2; - } - - /** - * Sets the Episodic Learning Codelet. - * - * @param episodicLearningCodelet - * the episodicLearningCodelet to set - */ - public void setEpisodicLearningCodelet(EpisodicLearningCodelet episodicLearningCodelet) { - this.episodicLearningCodelet = episodicLearningCodelet; - } - - /** - * Sets the Episodic Retrieval Codelet. - * - * @param episodicRetrievalCodelet - * the episodicRetrievalCodelet to set - */ - public void setEpisodicRetrievalCodelet(EpisodicRetrievalCodelet episodicRetrievalCodelet) { - this.episodicRetrievalCodelet = episodicRetrievalCodelet; - } - - /** - * Sets the Expectation Codelet. - * - * @param expectationCodelet - * the expectationCodelet to set - */ - public void setExpectationCodelet(ExpectationCodelet expectationCodelet) { - this.expectationCodelet = expectationCodelet; - } - - /** - * Sets the Consciousness Codelet. - * - * @param consciousnessCodelet - * the consciousnessCodelet to set - */ - public void setConsciousnessCodelet(ConsciousnessCodelet consciousnessCodelet) { - this.consciousnessCodelet = consciousnessCodelet; - } - - /** - * Sets the Soar Codelet. - * - * @param soarCodelet - * the soarCodelet to set - */ - public void setSoarCodelet(SoarCodelet soarCodelet) { - this.soarCodelet = soarCodelet; - } - - /** - * Sets the Goal Codelet. - * - * @param goalCodelet - * the goalCodelet to set - */ - public void setGoalCodelet(GoalCodelet goalCodelet) { - this.goalCodelet = goalCodelet; - } - - /** - * Sets the Appraisal Codelet. - * - * @param appraisalCodelet - * the appraisalCodelet to set - */ - public void setAppraisalCodelet(AppraisalCodelet appraisalCodelet) { - this.appraisalCodelet = appraisalCodelet; - } - - /** - * @param actionFromPlanningCodelets the actionFromPlanningCodelets to set - */ - public void setActionFromPlanningCodelets(List actionFromPlanningCodelets) { - this.actionFromPlanningCodelets = actionFromPlanningCodelets; - } - - /** - * @param actionFromPerceptionCodelets the actionFromPerceptionCodelets to set - */ - public void setActionFromPerceptionCodelets(List actionFromPerceptionCodelets) { - this.actionFromPerceptionCodelets = actionFromPerceptionCodelets; - } - - /** - * @param behaviorCodelets the behaviorCodelets to set - */ - public void setBehaviorCodelets(List behaviorCodelets) { - this.behaviorCodelets = behaviorCodelets; - } + } + /* + * Outputs + */ + Memory attentionMemoryOutput = createMemoryObject(attentionCodeletSystem1.getId()); + attentionCodeletSystem1.addOutput(attentionMemoryOutput); + attentionCodeletSystem1.setOutputFilteredPerceptsMO(attentionMemoryOutput); + insertCodelet(attentionCodeletSystem1); + } + } + + private void mountSoarCodelet() { + if (soarCodelet != null) { + soarCodelet.addInput(createMemoryObject(WorkingMemory.WORKING_MEMORY_INPUT, getWorkingMemory())); + soarCodelet.addOutput(createMemoryObject(soarCodelet.getId())); + insertCodelet(soarCodelet); + } + } + + private void mountWorkingMemory() { + if (getWorkingMemory() != null) { + if (attentionCodeletSystem1 != null) { + getWorkingMemory().setCurrentPerceptionMemory(attentionCodeletSystem1.getOutputFilteredPerceptsMO()); + } + } + } + + /** + * Sets the Sensory Codelets. + * + * @deprecated instead, add Sensory Codelets using the interface ISensoryCodelet + * + * @param sensoryCodelets + * the sensoryCodelets to set + */ + @Deprecated + public void setSensoryCodelets(List sensoryCodelets) { + this.sensoryCodelets = new ArrayList(); + this.sensoryCodelets.addAll(sensoryCodelets); + } + + /** + * Sets the Perceptual Codelets. + * + * @param perceptualCodelets + * the perceptualCodelets to set + */ + public void setPerceptualCodelets(List perceptualCodelets) { + this.perceptualCodelets = perceptualCodelets; + } + + /** + * Sets the Mood Codelets. + * + * @param moodCodelets + * the moodCodelets to set + */ + public void setMoodCodelets(List moodCodelets) { + this.moodCodelets = moodCodelets; + } + + /** + * Sets the Motivational Codelets. + * + * @param motivationalCodelets + * the motivationalCodelets to set + */ + public void setMotivationalCodelets(List motivationalCodelets) { + this.motivationalCodelets = motivationalCodelets; + } + + /** + * Sets the System 1 Attention Codelet. + * + * @param attentionCodeletSystem1 + * the attentionCodeletSystem1 to set + */ + public void setAttentionCodeletSystem1(AttentionCodelet attentionCodeletSystem1) { + this.attentionCodeletSystem1 = attentionCodeletSystem1; + } + + /** + * Sets the Emotional Codelets. + * + * @param emotionalCodelets + * the emotionalCodelets to set + */ + public void setEmotionalCodelets(List emotionalCodelets) { + this.emotionalCodelets = emotionalCodelets; + } + + /** + * Sets the Motor Codelets. + * + * @deprecated instead, add Motor Codelets using the interface IMotorCodelet + * @param motorCodelets + * the motorCodelets to set + */ + @Deprecated + public void setMotorCodelets(List motorCodelets) { + this.motorCodelets = new ArrayList(); + this.motorCodelets.addAll(motorCodelets); + } + + /** + * Sets the System 2 Attention Codelets + * + * @param attentionCodeletsSystem2 + * the attentionCodeletsSystem2 to set + */ + public void setAttentionCodeletsSystem2( + List attentionCodeletsSystem2) { + this.attentionCodeletsSystem2 = attentionCodeletsSystem2; + } + + /** + * Sets the Episodic Learning Codelet. + * + * @param episodicLearningCodelet + * the episodicLearningCodelet to set + */ + public void setEpisodicLearningCodelet(EpisodicLearningCodelet episodicLearningCodelet) { + this.episodicLearningCodelet = episodicLearningCodelet; + } + + /** + * Sets the Episodic Retrieval Codelet. + * + * @param episodicRetrievalCodelet + * the episodicRetrievalCodelet to set + */ + public void setEpisodicRetrievalCodelet(EpisodicRetrievalCodelet episodicRetrievalCodelet) { + this.episodicRetrievalCodelet = episodicRetrievalCodelet; + } + + /** + * Sets the Expectation Codelet. + * + * @param expectationCodelet + * the expectationCodelet to set + */ + public void setExpectationCodelet(ExpectationCodelet expectationCodelet) { + this.expectationCodelet = expectationCodelet; + } + + /** + * Sets the Consciousness Codelet. + * + * @param consciousnessCodelet + * the consciousnessCodelet to set + */ + public void setConsciousnessCodelet(ConsciousnessCodelet consciousnessCodelet) { + this.consciousnessCodelet = consciousnessCodelet; + } + + /** + * Sets the Soar Codelet. + * + * @param soarCodelet + * the soarCodelet to set + */ + public void setSoarCodelet(SoarCodelet soarCodelet) { + this.soarCodelet = soarCodelet; + } + + /** + * Sets the Goal Codelet. + * + * @param goalCodelet + * the goalCodelet to set + */ + public void setGoalCodelet(GoalCodelet goalCodelet) { + this.goalCodelet = goalCodelet; + } + + /** + * Sets the Appraisal Codelet. + * + * @param appraisalCodelet + * the appraisalCodelet to set + */ + public void setAppraisalCodelet(AppraisalCodelet appraisalCodelet) { + this.appraisalCodelet = appraisalCodelet; + } + + /** + * @param actionFromPlanningCodelets the actionFromPlanningCodelets to set + */ + public void setActionFromPlanningCodelets(List actionFromPlanningCodelets) { + this.actionFromPlanningCodelets = actionFromPlanningCodelets; + } + + /** + * @param actionFromPerceptionCodelets the actionFromPerceptionCodelets to set + */ + public void setActionFromPerceptionCodelets(List actionFromPerceptionCodelets) { + this.actionFromPerceptionCodelets = actionFromPerceptionCodelets; + } + + /** + * @param behaviorCodelets the behaviorCodelets to set + */ + public void setBehaviorCodelets(List behaviorCodelets) { + this.behaviorCodelets = behaviorCodelets; + } - /** - * @param sensoryCodelets the sensoryCodelets to set - */ - public void setISensoryCodelets(List sensoryCodelets) { - this.sensoryCodelets = sensoryCodelets; - } - - /** - * @param motorCodelets the motorCodelets to set - */ - public void setIMotorCodelets(List motorCodelets) { - this.motorCodelets = motorCodelets; - } - - /** - * Gets the MECA Mind id - * - * @return the id - */ - public String getId() { - return id; - } - - /** - * Sets the MECA Mind id - * - * @param id - * the id to set. - */ - public void setId(String id) { - this.id = id; - } - - /** - * Gets the Mood Codelets. - * - * @return the mood codelets. - */ - public List getMoodCodelets() { - return moodCodelets; - } - - /** - * Gets the Motivational Codelets. - * - * @return the Motivational Codelets. - */ - public List getMotivationalCodelets() { - return motivationalCodelets; - } - - /** - * Gets the Emotional Codelets. - * - * @return the Emotional Codelets. - */ - public List getEmotionalCodelets() { - return emotionalCodelets; - } - - /** - * Gets the Goal Codelets. - * - * @return the Goal Codelet. - */ - public GoalCodelet getGoalCodelet() { - return goalCodelet; - } - - /** - * Gets the Appraisal Codelet. - * - * @return the Appraisal Codelet. - */ - public AppraisalCodelet getAppraisalCodelet() { - return appraisalCodelet; - } - - /** - * Gets the Working Memory. - * - * @return the Working Memory. - */ - public WorkingMemory getWorkingMemory() { - return workingMemory; - } - - /** - * Sets the Working Memory. - * - * @param workingMemory - * the working memory to set. - */ - public void setWorkingMemory(WorkingMemory workingMemory) { - this.workingMemory = workingMemory; - } - - /** - * Gets the Sensory Codelets. - * - * @return the sensoryCodelets. - */ - public List getSensoryCodelets() { - return sensoryCodelets; - } - - /** - * Gets the Perceptual Codelets. - * - * @return the perceptualCodelets. - */ - public List getPerceptualCodelets() { - return perceptualCodelets; - } - - /** - * Gets the Attention Codelet from System 1. - * - * @return the attentionCodeletSystem1. - */ - public AttentionCodelet getAttentionCodeletSystem1() { - return attentionCodeletSystem1; - } - - /** - * Gets the Motor Codelets. - * - * @return the motorCodelets. - */ - public List getMotorCodelets() { - return motorCodelets; - } - - /** - * Gets the Attention Codelets from System 2. - * - * @return the attentionCodeletsSystem2. - */ - public List getAttentionCodeletsSystem2() { - return attentionCodeletsSystem2; - } - - /** - * Gets the Episodic Learning Codelet. - * - * @return the episodicLearningCodelet. - */ - public EpisodicLearningCodelet getEpisodicLearningCodelet() { - return episodicLearningCodelet; - } - - /** - * Gets the Episodic Retrieval Codelet. - * - * @return the episodicRetrievalCodelet. - */ - public EpisodicRetrievalCodelet getEpisodicRetrievalCodelet() { - return episodicRetrievalCodelet; - } - - /** - * Gets the Expectation Codelet. - * - * @return the expectationCodelet. - */ - public ExpectationCodelet getExpectationCodelet() { - return expectationCodelet; - } - - /** - * Gets the Consciousness Codelet. - * - * @return the consciousnessCodelet. - */ - public ConsciousnessCodelet getConsciousnessCodelet() { - return consciousnessCodelet; - } - - /** - * Gets the Soar Codelet. - * - * @return the soarCodelet. - */ - public SoarCodelet getSoarCodelet() { - return soarCodelet; - } - - /** - * @return the behaviorCodelets - */ - public List getBehaviorCodelets() { - return behaviorCodelets; - } - - /** - * @return the actionFromPlanningCodelets - */ - public List getActionFromPlanningCodelets() { - return actionFromPlanningCodelets; - } - - /** - * @return the actionFromPerceptionCodelets - */ - public List getActionFromPerceptionCodelets() { - return actionFromPerceptionCodelets; - } + /** + * @param sensoryCodelets the sensoryCodelets to set + */ + public void setISensoryCodelets(List sensoryCodelets) { + this.sensoryCodelets = sensoryCodelets; + } + + /** + * @param motorCodelets the motorCodelets to set + */ + public void setIMotorCodelets(List motorCodelets) { + this.motorCodelets = motorCodelets; + } + + /** + * Gets the MECA Mind id + * + * @return the id + */ + public String getId() { + return id; + } + + /** + * Sets the MECA Mind id + * + * @param id + * the id to set. + */ + public void setId(String id) { + this.id = id; + } + + /** + * Gets the Mood Codelets. + * + * @return the mood codelets. + */ + public List getMoodCodelets() { + return moodCodelets; + } + + /** + * Gets the Motivational Codelets. + * + * @return the Motivational Codelets. + */ + public List getMotivationalCodelets() { + return motivationalCodelets; + } + + /** + * Gets the Emotional Codelets. + * + * @return the Emotional Codelets. + */ + public List getEmotionalCodelets() { + return emotionalCodelets; + } + + /** + * Gets the Goal Codelets. + * + * @return the Goal Codelet. + */ + public GoalCodelet getGoalCodelet() { + return goalCodelet; + } + + /** + * Gets the Appraisal Codelet. + * + * @return the Appraisal Codelet. + */ + public AppraisalCodelet getAppraisalCodelet() { + return appraisalCodelet; + } + + /** + * Gets the Working Memory. + * + * @return the Working Memory. + */ + public WorkingMemory getWorkingMemory() { + return workingMemory; + } + + /** + * Sets the Working Memory. + * + * @param workingMemory + * the working memory to set. + */ + public void setWorkingMemory(WorkingMemory workingMemory) { + this.workingMemory = workingMemory; + } + + /** + * Gets the Sensory Codelets. + * + * @return the sensoryCodelets. + */ + public List getSensoryCodelets() { + return sensoryCodelets; + } + + /** + * Gets the Perceptual Codelets. + * + * @return the perceptualCodelets. + */ + public List getPerceptualCodelets() { + return perceptualCodelets; + } + + /** + * Gets the Attention Codelet from System 1. + * + * @return the attentionCodeletSystem1. + */ + public AttentionCodelet getAttentionCodeletSystem1() { + return attentionCodeletSystem1; + } + + /** + * Gets the Motor Codelets. + * + * @return the motorCodelets. + */ + public List getMotorCodelets() { + return motorCodelets; + } + + /** + * Gets the Attention Codelets from System 2. + * + * @return the attentionCodeletsSystem2. + */ + public List getAttentionCodeletsSystem2() { + return attentionCodeletsSystem2; + } + + /** + * Gets the Episodic Learning Codelet. + * + * @return the episodicLearningCodelet. + */ + public EpisodicLearningCodelet getEpisodicLearningCodelet() { + return episodicLearningCodelet; + } + + /** + * Gets the Episodic Retrieval Codelet. + * + * @return the episodicRetrievalCodelet. + */ + public EpisodicRetrievalCodelet getEpisodicRetrievalCodelet() { + return episodicRetrievalCodelet; + } + + /** + * Gets the Expectation Codelet. + * + * @return the expectationCodelet. + */ + public ExpectationCodelet getExpectationCodelet() { + return expectationCodelet; + } + + /** + * Gets the Consciousness Codelet. + * + * @return the consciousnessCodelet. + */ + public ConsciousnessCodelet getConsciousnessCodelet() { + return consciousnessCodelet; + } + + /** + * Gets the Soar Codelet. + * + * @return the soarCodelet. + */ + public SoarCodelet getSoarCodelet() { + return soarCodelet; + } + + /** + * @return the behaviorCodelets + */ + public List getBehaviorCodelets() { + return behaviorCodelets; + } + + /** + * @return the actionFromPlanningCodelets + */ + public List getActionFromPlanningCodelets() { + return actionFromPlanningCodelets; + } + + /** + * @return the actionFromPerceptionCodelets + */ + public List getActionFromPerceptionCodelets() { + return actionFromPerceptionCodelets; + } } diff --git a/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java b/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java index 4449b7a..0b2a739 100644 --- a/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java +++ b/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java @@ -46,7 +46,7 @@ public ActionSequencePlan(String[] actionIdSequence) { /** * Returns the id of the current ActionFromPlanningCodelet to be undertaken in the plan. * - * @return + * @return currentActionId */ public String getCurrentActionId() { return actionIdSequence[currentActionIdIndex]; diff --git a/src/main/java/br/unicamp/meca/models/ActionStep.java b/src/main/java/br/unicamp/meca/models/ActionStep.java new file mode 100644 index 0000000..15545cf --- /dev/null +++ b/src/main/java/br/unicamp/meca/models/ActionStep.java @@ -0,0 +1,43 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package br.unicamp.meca.models; + +import java.util.HashMap; +import java.util.Map; + +/** + * + * @author rgudwin + */ +public class ActionStep { + String actionId; + Map parameters; + + public ActionStep() { + actionId = ""; + parameters = new HashMap(); + } + + public String getActionId() { + return actionId; + } + + public void setActionId(String id) { + actionId = id; + } + + public Object getParameter(String paramId) { + return(parameters.get(paramId)); + } + + public void set(String paramId, Object param) { + if (parameters.get(paramId) == null) + parameters.put(paramId, param); + else + parameters.replace(paramId, param); + } + +} From f47d47c9e1a90a40cf2ee6d118152f5a3754aa9f Mon Sep 17 00:00:00 2001 From: Ricardo Gudwin Date: Mon, 10 Aug 2020 14:34:41 -0300 Subject: [PATCH 12/89] Changes to insert ActionStep as as step in ActionSequencePlan --- build.gradle | 2 +- .../meca/models/ActionSequencePlan.java | 14 ++++----- .../br/unicamp/meca/models/ActionStep.java | 30 +++++++++++++++---- .../codelets/ActionFromPlanningCodelet.java | 7 +++-- .../br/unicamp/meca/mind/MecaMindTest.java | 5 +++- .../Test1AndTest2BehaviorCodelet.java | 2 +- .../meca/models/ActionSequencePlanTest.java | 8 +++-- 7 files changed, 46 insertions(+), 22 deletions(-) diff --git a/build.gradle b/build.gradle index 43bad48..33b0f28 100644 --- a/build.gradle +++ b/build.gradle @@ -31,7 +31,7 @@ repositories { dependencies { //api 'com.github.CST-Group:cst:0.5.0' - api ':cst:0.5.0-full' + api ':cst:0.5.1-full' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' testImplementation 'org.ros.rosjava_messages:rosjava_test_msgs:0.3.0' diff --git a/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java b/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java index 0b2a739..638e0a6 100644 --- a/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java +++ b/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java @@ -6,8 +6,8 @@ * http://www.gnu.org/licenses/lgpl.html * * * * Contributors: * - * R. R. Gudwin, A. L. O. Paraense, E. Froes, W. Gibaut, * - * and K. Raizer. * + * R. R. Gudwin, A. L. O. Paraense, E. Froes, W. Gibaut, * + * and K. Raizer. * * * ******************************************************************************/ package br.unicamp.meca.models; @@ -27,7 +27,7 @@ */ public class ActionSequencePlan { - private String[] actionIdSequence; + private ActionStep[] actionIdSequence; private int currentActionIdIndex = 0; @@ -39,7 +39,7 @@ public class ActionSequencePlan { * the list of ids of ActionFromPlanningCodelet(s) to be executed * in sequence following this plan. */ - public ActionSequencePlan(String[] actionIdSequence) { + public ActionSequencePlan(ActionStep[] actionIdSequence) { this.actionIdSequence = actionIdSequence; } @@ -48,21 +48,21 @@ public ActionSequencePlan(String[] actionIdSequence) { * * @return currentActionId */ - public String getCurrentActionId() { + public ActionStep getCurrentActionStep() { return actionIdSequence[currentActionIdIndex]; } /** * @return the actionIdSequence */ - public String[] getActionIdSequence() { + public ActionStep[] getActionStepSequence() { return actionIdSequence; } /** * @param actionIdSequence the actionIdSequence to set */ - public void setActionIdSequence(String[] actionIdSequence) { + public void setActionStepSequence(ActionStep[] actionIdSequence) { this.actionIdSequence = actionIdSequence; } diff --git a/src/main/java/br/unicamp/meca/models/ActionStep.java b/src/main/java/br/unicamp/meca/models/ActionStep.java index 15545cf..178334d 100644 --- a/src/main/java/br/unicamp/meca/models/ActionStep.java +++ b/src/main/java/br/unicamp/meca/models/ActionStep.java @@ -1,8 +1,15 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ +/******************************************************************************* + * Copyright (c) 2019 DCA-FEEC-UNICAMP and Ericsson Research * + * All rights reserved. This program and the accompanying materials * + * are made available under the terms of the GNU Lesser Public License v3 * + * which accompanies this distribution, and is available at * + * http://www.gnu.org/licenses/lgpl.html * + * * + * Contributors: * + * R. R. Gudwin, A. L. O. Paraense, E. Froes, W. Gibaut, * + * and K. Raizer. * + * * + ******************************************************************************/ package br.unicamp.meca.models; import java.util.HashMap; @@ -21,6 +28,17 @@ public ActionStep() { parameters = new HashMap(); } + public ActionStep(String acId) { + super(); + actionId = acId; + } + + public ActionStep(String acId, Map par) { + super(); + actionId = acId; + parameters = par; + } + public String getActionId() { return actionId; } @@ -33,7 +51,7 @@ public Object getParameter(String paramId) { return(parameters.get(paramId)); } - public void set(String paramId, Object param) { + public void setParameter(String paramId, Object param) { if (parameters.get(paramId) == null) parameters.put(paramId, param); else diff --git a/src/main/java/br/unicamp/meca/system1/codelets/ActionFromPlanningCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/ActionFromPlanningCodelet.java index 242ce85..59b760f 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/ActionFromPlanningCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/ActionFromPlanningCodelet.java @@ -19,6 +19,7 @@ import br.unicamp.cst.core.exceptions.CodeletActivationBoundsException; import br.unicamp.meca.mind.MecaMind; import br.unicamp.meca.models.ActionSequencePlan; +import br.unicamp.meca.models.ActionStep; /** * This class represents the MECA Action From Planning Codelet. This Action From Planning @@ -113,9 +114,9 @@ public void calculateActivation() { if(actionSequencePlanMemoryContainer != null && actionSequencePlanMemoryContainer.getI() != null && actionSequencePlanMemoryContainer.getI() instanceof ActionSequencePlan) { ActionSequencePlan actionSequencePlan = (ActionSequencePlan) actionSequencePlanMemoryContainer.getI(); - String currentActionId = actionSequencePlan.getCurrentActionId(); + ActionStep currentActionId = actionSequencePlan.getCurrentActionStep(); - if(currentActionId != null && currentActionId.equalsIgnoreCase(id)) { + if(currentActionId != null && currentActionId.getActionId().equalsIgnoreCase(id)) { setActivation(actionSequencePlanMemoryContainer.getEvaluation()); }else { setActivation(0.0d); @@ -133,7 +134,7 @@ public void proc() { if(actionSequencePlanMemoryContainer != null && actionSequencePlanMemoryContainer.getI() != null && actionSequencePlanMemoryContainer.getI() instanceof ActionSequencePlan) { ActionSequencePlan actionSequencePlan = (ActionSequencePlan) actionSequencePlanMemoryContainer.getI(); - String currentActionId = actionSequencePlan.getCurrentActionId(); + String currentActionId = actionSequencePlan.getCurrentActionStep().getActionId(); if(currentActionId != null && currentActionId.equalsIgnoreCase(id)) { proc(perceptualMemories, broadcastMemory, motorMemory); diff --git a/src/test/java/br/unicamp/meca/mind/MecaMindTest.java b/src/test/java/br/unicamp/meca/mind/MecaMindTest.java index 4e789c2..4dbfde7 100644 --- a/src/test/java/br/unicamp/meca/mind/MecaMindTest.java +++ b/src/test/java/br/unicamp/meca/mind/MecaMindTest.java @@ -28,6 +28,7 @@ import br.unicamp.meca.mind.sensory.TestPerceptionSensoryCodelet; import br.unicamp.meca.mind.sensory.TestPlanningSensoryCodelet; import br.unicamp.meca.models.ActionSequencePlan; +import br.unicamp.meca.models.ActionStep; import br.unicamp.meca.system1.codelets.ActionFromPerceptionCodelet; import br.unicamp.meca.system1.codelets.ActionFromPlanningCodelet; import br.unicamp.meca.system1.codelets.BehaviorCodelet; @@ -152,7 +153,9 @@ public static void setup() throws InterruptedException { List behaviorCodelets = new ArrayList<>(); - ActionSequencePlan test1Test2ActionSequence = new ActionSequencePlan(new String[] {"Test1ActionFromPlanningCodelet","Test2ActionFromPlanningCodelets"}); + ActionStep as1 = new ActionStep("Test1ActionFromPlanningCodelet"); + ActionStep as2 = new ActionStep("Test2ActionFromPlanningCodelet"); + ActionSequencePlan test1Test2ActionSequence = new ActionSequencePlan(new ActionStep[] {as1,as2}); Test1AndTest2BehaviorCodelet test1AndTest2BehaviorCodelet = new Test1AndTest2BehaviorCodelet("Test1AndTest2BehaviorCodelet", perceptualCodeletsIds, testMotivationalFromPlanningCodeletIds, null, test1Test2ActionSequence); behaviorCodelets.add(test1AndTest2BehaviorCodelet); diff --git a/src/test/java/br/unicamp/meca/mind/behavior/Test1AndTest2BehaviorCodelet.java b/src/test/java/br/unicamp/meca/mind/behavior/Test1AndTest2BehaviorCodelet.java index e522225..060f32e 100644 --- a/src/test/java/br/unicamp/meca/mind/behavior/Test1AndTest2BehaviorCodelet.java +++ b/src/test/java/br/unicamp/meca/mind/behavior/Test1AndTest2BehaviorCodelet.java @@ -23,7 +23,7 @@ public Test1AndTest2BehaviorCodelet(String id, ArrayList perceptualCodel @Override public void trackActionSequencePlan(ArrayList perceptualMemories, ActionSequencePlan actionSequencePlan) { - if(actionSequencePlan == null || actionSequencePlan.getActionIdSequence() == null) { + if(actionSequencePlan == null || actionSequencePlan.getActionStepSequence() == null) { return; } diff --git a/src/test/java/br/unicamp/meca/models/ActionSequencePlanTest.java b/src/test/java/br/unicamp/meca/models/ActionSequencePlanTest.java index 3a20afc..5b9de13 100644 --- a/src/test/java/br/unicamp/meca/models/ActionSequencePlanTest.java +++ b/src/test/java/br/unicamp/meca/models/ActionSequencePlanTest.java @@ -20,12 +20,14 @@ public void setUp() { @Test public void testGetCurrentActionId() { - ActionSequencePlan landAndStopSequencePlan = new ActionSequencePlan(new String[] {"Land","Stop"}); + ActionStep as1 = new ActionStep("Land"); + ActionStep as2 = new ActionStep("Stop"); + ActionSequencePlan landAndStopSequencePlan = new ActionSequencePlan(new ActionStep[] {as1,as2}); - assertEquals(landAndStopSequencePlan.getCurrentActionId(), "Land"); + assertEquals(landAndStopSequencePlan.getCurrentActionStep().getActionId(), "Land"); landAndStopSequencePlan.setCurrentActionIdIndex(1); - assertEquals(landAndStopSequencePlan.getCurrentActionId(), "Stop"); + assertEquals(landAndStopSequencePlan.getCurrentActionStep().getActionId(), "Stop"); } } From b75153b51230c4f33aad87a5284f94abeb640165 Mon Sep 17 00:00:00 2001 From: Ricardo Gudwin Date: Thu, 13 Aug 2020 08:46:03 -0300 Subject: [PATCH 13/89] Changes in ActionSequencePlan and ActionStep --- .../meca/models/ActionSequencePlan.java | 5 +++ .../br/unicamp/meca/models/ActionStep.java | 22 +++++++++- .../unicamp/meca/models/ActionStepTest.java | 40 +++++++++++++++++++ 3 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 src/test/java/br/unicamp/meca/models/ActionStepTest.java diff --git a/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java b/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java index 638e0a6..dda7c3b 100644 --- a/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java +++ b/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java @@ -79,4 +79,9 @@ public int getCurrentActionIdIndex() { public void setCurrentActionIdIndex(int currentActionIdIndex) { this.currentActionIdIndex = currentActionIdIndex; } + + public void gotoNextAction() { + if (currentActionIdIndex < actionIdSequence.length-1) + currentActionIdIndex++; + } } diff --git a/src/main/java/br/unicamp/meca/models/ActionStep.java b/src/main/java/br/unicamp/meca/models/ActionStep.java index 178334d..08e90d3 100644 --- a/src/main/java/br/unicamp/meca/models/ActionStep.java +++ b/src/main/java/br/unicamp/meca/models/ActionStep.java @@ -29,12 +29,12 @@ public ActionStep() { } public ActionStep(String acId) { - super(); + this(); actionId = acId; } public ActionStep(String acId, Map par) { - super(); + this(); actionId = acId; parameters = par; } @@ -48,6 +48,7 @@ public void setActionId(String id) { } public Object getParameter(String paramId) { + if (parameters == null) System.out.println("Parameters is null"); return(parameters.get(paramId)); } @@ -58,4 +59,21 @@ public void setParameter(String paramId, Object param) { parameters.replace(paramId, param); } + public Map getParameters() { + return(parameters); + } + + public void setParameters(Map par) { + parameters = par; + } + + public int getNumberOfParameters() { + if(parameters == null) return(-1); + return(parameters.size()); + } + + public void unsetParameter(String param) { + parameters.remove(param); + } + } diff --git a/src/test/java/br/unicamp/meca/models/ActionStepTest.java b/src/test/java/br/unicamp/meca/models/ActionStepTest.java new file mode 100644 index 0000000..c0baf83 --- /dev/null +++ b/src/test/java/br/unicamp/meca/models/ActionStepTest.java @@ -0,0 +1,40 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package br.unicamp.meca.models; +import java.util.logging.Logger; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +/** + * + * @author rgudwin + */ +public class ActionStepTest { + + + public void setUp() { + System.out.println("########## ActionStep TESTS ##########"); + } + + @Test + public void testActionStep() { + ActionStep as1 = new ActionStep(); + assertEquals(as1.getNumberOfParameters(),0); + ActionStep as2 = new ActionStep("TestAction"); + assertEquals(as2.getNumberOfParameters(),0); + assertEquals(as2.getActionId(),"TestAction"); + as2.setParameter("param", "value"); + assertEquals(as2.getNumberOfParameters(),1); + assertEquals(as2.getParameter("param"),"value"); + as2.setParameter("param", "value2"); + assertEquals(as2.getParameter("param"),"value2"); + as2.unsetParameter("param"); + assertEquals(as2.getNumberOfParameters(),0); + } + + + +} From a45a5166032c1f0ea83468d60e8e58c9ad1ab30e Mon Sep 17 00:00:00 2001 From: Andre Paraense Date: Fri, 14 Aug 2020 18:07:47 +0100 Subject: [PATCH 14/89] Compiling against last CST version --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index fadabab..a839cf7 100644 --- a/build.gradle +++ b/build.gradle @@ -30,8 +30,8 @@ repositories { } dependencies { - //api 'com.github.CST-Group:cst:0.5.0' - api ':cst:0.5.1-full' + api 'com.github.CST-Group:cst:0.5.1' + //api ':cst:0.5.1-full' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' testImplementation 'org.ros.rosjava_messages:rosjava_test_msgs:0.3.0' From 5d98ba085752e360f1831847be0ead679b402db2 Mon Sep 17 00:00:00 2001 From: Andre Paraense Date: Fri, 14 Aug 2020 18:59:50 +0100 Subject: [PATCH 15/89] ActivityTrackingCodelet --- .../java/br/unicamp/meca/mind/MecaMind.java | 1574 +++++++++-------- .../codelets/ActivityTrackingCodelet.java | 148 ++ 2 files changed, 958 insertions(+), 764 deletions(-) create mode 100644 src/main/java/br/unicamp/meca/system1/codelets/ActivityTrackingCodelet.java diff --git a/src/main/java/br/unicamp/meca/mind/MecaMind.java b/src/main/java/br/unicamp/meca/mind/MecaMind.java index c337b12..fe96978 100644 --- a/src/main/java/br/unicamp/meca/mind/MecaMind.java +++ b/src/main/java/br/unicamp/meca/mind/MecaMind.java @@ -25,6 +25,7 @@ import br.unicamp.meca.memory.WorkingMemory; import br.unicamp.meca.system1.codelets.ActionFromPerceptionCodelet; import br.unicamp.meca.system1.codelets.ActionFromPlanningCodelet; +import br.unicamp.meca.system1.codelets.ActivityTrackingCodelet; import br.unicamp.meca.system1.codelets.AttentionCodelet; import br.unicamp.meca.system1.codelets.BehaviorCodelet; import br.unicamp.meca.system1.codelets.EmotionalCodelet; @@ -53,795 +54,840 @@ */ public class MecaMind extends Mind { - public static final String ACTION_SEQUENCE_PLAN_ID = "ACTION_SEQUENCE_PLAN_ID"; - public static final String ACTION_SEQUENCE_PLAN_REQUEST_ID = "ACTION_SEQUENCE_PLAN_REQUEST_ID"; - - /* - * System 1 - */ - - private List sensoryCodelets; - private List perceptualCodelets; - private List moodCodelets; - private List motivationalCodelets; - private AttentionCodelet attentionCodeletSystem1; - private List emotionalCodelets; - private List actionFromPlanningCodelets; - private List actionFromPerceptionCodelets; - private List behaviorCodelets; - private List motorCodelets; - private Memory actionSequencePlanMemoryContainer; - private Memory actionSequencePlanRequestMemoryContainer; - - /* - * System 2 - */ - - private List attentionCodeletsSystem2; - private EpisodicLearningCodelet episodicLearningCodelet; - private EpisodicRetrievalCodelet episodicRetrievalCodelet; - private ExpectationCodelet expectationCodelet; - private ConsciousnessCodelet consciousnessCodelet; - private SoarCodelet soarCodelet; - private GoalCodelet goalCodelet; - private AppraisalCodelet appraisalCodelet; - private WorkingMemory workingMemory; - - private String id; - - /** - * Creates the MECA Mind. - */ - public MecaMind() { - setId(UUID.randomUUID().toString()); - setWorkingMemory(new WorkingMemory(getId())); - } - - /** - * Creates the MECA Mind. - * - * @param id - * the id of the MECA mind. Must be unique per MECA mind. - */ - public MecaMind(String id) { - setId(id); - setWorkingMemory(new WorkingMemory(getId())); - } - - /** - * Mounts the MECA Mind. After creating the MECA Mind's instance and setting - * all the codelets inside it, this method is responsible for binding - * together all codelets inside the mind, creating memories (objects and - * containers) and setting them either as inputs or outputs of each codelet, - * according to MECA's reference architecture. - *

- * This method must be called before running the MECA Agent. - */ - public void mountMecaMind() { - mountSensoryCodelets(); - mountPerceptualCodelets(); - mountMotorCodelets(); - mountAttentionCodelets(); - mountWorkingMemory(); - mountSoarCodelet(); - mountMotivationalCodelets(); - mountActionSequencePlanMemory(); - mountBehaviorCodelets(); - mountActionFromPlanningCodelets(); - mountActionFromPerceptionCodelets(); - mountModules(); - } - - private void mountActionSequencePlanMemory() { - actionSequencePlanMemoryContainer = createMemoryContainer(ACTION_SEQUENCE_PLAN_ID); - actionSequencePlanRequestMemoryContainer = createMemoryContainer(ACTION_SEQUENCE_PLAN_REQUEST_ID); - } - - private void mountModules() { -// if (getMotivationalCodelets() != null) { -// if (getMotivationalCodelets().size() > 0) { -// List mtcodelets = getMotivationalCodelets(); -//// getMotivationalSubsystemModule() -//// .setMotivationalCodelets((List) mtcodelets); -// } -// } - if (getSoarCodelet() != null) { - getPlansSubsystemModule().setjSoarCodelet(getSoarCodelet()); - } - } - - private void mountPerceptualCodelets() { - if (perceptualCodelets != null) { - for (PerceptualCodelet perceptualCodelet : perceptualCodelets) { - if (perceptualCodelet != null && perceptualCodelet.getId() != null) { - insertCodelet(perceptualCodelet); - /* - * Inputs - */ - if (sensoryCodelets != null) { - for (ISensoryCodelet sensoryCodelet : sensoryCodelets) { - if (sensoryCodelet != null && sensoryCodelet.getId() != null) { - ArrayList sensoryCodeletsIds = perceptualCodelet.getSensoryCodeletsIds(); - if (sensoryCodeletsIds != null) { - for (String sensoryCodeletId : sensoryCodeletsIds) { - if (sensoryCodeletId != null && sensoryCodeletId.equalsIgnoreCase(sensoryCodelet.getId())) { - perceptualCodelet.addInputs(sensoryCodelet.getOutputs()); + public static final String ACTION_SEQUENCE_PLAN_ID = "ACTION_SEQUENCE_PLAN_ID"; + public static final String ACTION_SEQUENCE_PLAN_REQUEST_ID = "ACTION_SEQUENCE_PLAN_REQUEST_ID"; + + /* + * System 1 + */ + + private List sensoryCodelets; + private List perceptualCodelets; + private List moodCodelets; + private List motivationalCodelets; + private AttentionCodelet attentionCodeletSystem1; + private List emotionalCodelets; + private List actionFromPlanningCodelets; + private List actionFromPerceptionCodelets; + private List behaviorCodelets; + private List motorCodelets; + private Memory actionSequencePlanMemoryContainer; + private Memory actionSequencePlanRequestMemoryContainer; + private ActivityTrackingCodelet activityTrackingCodelet; + + /* + * System 2 + */ + + private List attentionCodeletsSystem2; + private EpisodicLearningCodelet episodicLearningCodelet; + private EpisodicRetrievalCodelet episodicRetrievalCodelet; + private ExpectationCodelet expectationCodelet; + private ConsciousnessCodelet consciousnessCodelet; + private SoarCodelet soarCodelet; + private GoalCodelet goalCodelet; + private AppraisalCodelet appraisalCodelet; + private WorkingMemory workingMemory; + + private String id; + + /** + * Creates the MECA Mind. + */ + public MecaMind() { + setId(UUID.randomUUID().toString()); + setWorkingMemory(new WorkingMemory(getId())); + } + + /** + * Creates the MECA Mind. + * + * @param id + * the id of the MECA mind. Must be unique per MECA mind. + */ + public MecaMind(String id) { + setId(id); + setWorkingMemory(new WorkingMemory(getId())); + } + + /** + * Mounts the MECA Mind. After creating the MECA Mind's instance and setting + * all the codelets inside it, this method is responsible for binding + * together all codelets inside the mind, creating memories (objects and + * containers) and setting them either as inputs or outputs of each codelet, + * according to MECA's reference architecture. + *

+ * This method must be called before running the MECA Agent. + */ + public void mountMecaMind() { + mountSensoryCodelets(); + mountPerceptualCodelets(); + mountMotorCodelets(); + mountAttentionCodelets(); + mountWorkingMemory(); + mountSoarCodelet(); + mountMotivationalCodelets(); + mountActionSequencePlanMemory(); + mountBehaviorCodelets(); + mountActivityTrackingCodelet(); + mountActionFromPlanningCodelets(); + mountActionFromPerceptionCodelets(); + mountModules(); + } + + private void mountActionSequencePlanMemory() { + actionSequencePlanMemoryContainer = createMemoryContainer(ACTION_SEQUENCE_PLAN_ID); + actionSequencePlanRequestMemoryContainer = createMemoryContainer(ACTION_SEQUENCE_PLAN_REQUEST_ID); + } + + private void mountModules() { + // if (getMotivationalCodelets() != null) { + // if (getMotivationalCodelets().size() > 0) { + // List mtcodelets = getMotivationalCodelets(); + //// getMotivationalSubsystemModule() + //// .setMotivationalCodelets((List) mtcodelets); + // } + // } + if (getSoarCodelet() != null) { + getPlansSubsystemModule().setjSoarCodelet(getSoarCodelet()); + } + } + + private void mountPerceptualCodelets() { + if (perceptualCodelets != null) { + for (PerceptualCodelet perceptualCodelet : perceptualCodelets) { + if (perceptualCodelet != null && perceptualCodelet.getId() != null) { + insertCodelet(perceptualCodelet); + /* + * Inputs + */ + if (sensoryCodelets != null) { + for (ISensoryCodelet sensoryCodelet : sensoryCodelets) { + if (sensoryCodelet != null && sensoryCodelet.getId() != null) { + ArrayList sensoryCodeletsIds = perceptualCodelet.getSensoryCodeletsIds(); + if (sensoryCodeletsIds != null) { + for (String sensoryCodeletId : sensoryCodeletsIds) { + if (sensoryCodeletId != null && sensoryCodeletId.equalsIgnoreCase(sensoryCodelet.getId())) { + perceptualCodelet.addInputs(sensoryCodelet.getOutputs()); + } + } + } + } + } } - } + /* + * Output + */ + MemoryObject perceptualMemory = createMemoryObject(perceptualCodelet.getId()); + perceptualCodelet.addOutput(perceptualMemory); } - } } - } - /* - * Output - */ - MemoryObject perceptualMemory = createMemoryObject(perceptualCodelet.getId()); - perceptualCodelet.addOutput(perceptualMemory); } - } - } - } - - private void mountSensoryCodelets() { - if (sensoryCodelets != null) { - for (ISensoryCodelet sensoryCodelet : sensoryCodelets) { - if (sensoryCodelet != null && sensoryCodelet.getId() != null) { - insertCodelet((Codelet) sensoryCodelet); - /* - * Output - */ - MemoryObject sensoryMemory = createMemoryObject(sensoryCodelet.getId()); - sensoryCodelet.addOutput(sensoryMemory); - } - } - } - } - - private void mountMotivationalCodelets() { - if (getMotivationalCodelets() != null) { - for (MotivationalCodelet motivationalCodelet : getMotivationalCodelets()) { - /* - * Input Sensors - */ - if (motivationalCodelet.getSensoryCodeletsIds() != null) { - List sensoryIds = motivationalCodelet.getSensoryCodeletsIds(); - for (String sensoryId : sensoryIds) { - if (sensoryCodelets != null) { - for (ISensoryCodelet sensoryCodelet : sensoryCodelets) { - if (sensoryCodelet.getId().equals(sensoryId)) { - motivationalCodelet.addInputs(sensoryCodelet.getOutputs()); + } + + private void mountSensoryCodelets() { + if (sensoryCodelets != null) { + for (ISensoryCodelet sensoryCodelet : sensoryCodelets) { + if (sensoryCodelet != null && sensoryCodelet.getId() != null) { + insertCodelet((Codelet) sensoryCodelet); + /* + * Output + */ + MemoryObject sensoryMemory = createMemoryObject(sensoryCodelet.getId()); + sensoryCodelet.addOutput(sensoryMemory); } - } } - } } - /* - * Input Drives - */ - if (motivationalCodelet.getMotivationalCodeletsIds() != null) { - HashMap motivationalCodeletsIds = motivationalCodelet.getMotivationalCodeletsIds(); - for (Map.Entry motivationalCodeletId : motivationalCodeletsIds.entrySet()) { - for (MotivationalCodelet motivationalCodeletInput : getMotivationalCodelets()) { - if (motivationalCodeletInput.getId().equals(motivationalCodeletId.getKey())) { - HashMap driveRelevance = new HashMap<>(); - driveRelevance.put(motivationalCodeletInput.getOutputDriveMO(), - motivationalCodeletId.getValue()); - motivationalCodelet.addInput(this.createMemoryObject( - motivationalCodeletInput.getOutputDriveMO().getName(), driveRelevance)); - } + } + + private void mountMotivationalCodelets() { + if (getMotivationalCodelets() != null) { + for (MotivationalCodelet motivationalCodelet : getMotivationalCodelets()) { + /* + * Input Sensors + */ + if (motivationalCodelet.getSensoryCodeletsIds() != null) { + List sensoryIds = motivationalCodelet.getSensoryCodeletsIds(); + for (String sensoryId : sensoryIds) { + if (sensoryCodelets != null) { + for (ISensoryCodelet sensoryCodelet : sensoryCodelets) { + if (sensoryCodelet.getId().equals(sensoryId)) { + motivationalCodelet.addInputs(sensoryCodelet.getOutputs()); + } + } + } + } + } + /* + * Input Drives + */ + if (motivationalCodelet.getMotivationalCodeletsIds() != null) { + HashMap motivationalCodeletsIds = motivationalCodelet.getMotivationalCodeletsIds(); + for (Map.Entry motivationalCodeletId : motivationalCodeletsIds.entrySet()) { + for (MotivationalCodelet motivationalCodeletInput : getMotivationalCodelets()) { + if (motivationalCodeletInput.getId().equals(motivationalCodeletId.getKey())) { + HashMap driveRelevance = new HashMap<>(); + driveRelevance.put(motivationalCodeletInput.getOutputDriveMO(), + motivationalCodeletId.getValue()); + motivationalCodelet.addInput(this.createMemoryObject( + motivationalCodeletInput.getOutputDriveMO().getName(), driveRelevance)); + } + } + } + } + /* + * Output Drives + */ + MemoryObject outputDrive = this.createMemoryObject(motivationalCodelet.getId() + "_DRIVE_MO"); + motivationalCodelet.addOutput(outputDrive); + insertCodelet(motivationalCodelet); } - } } - /* - * Output Drives - */ - MemoryObject outputDrive = this.createMemoryObject(motivationalCodelet.getId() + "_DRIVE_MO"); - motivationalCodelet.addOutput(outputDrive); - insertCodelet(motivationalCodelet); - } - } - } - - private void mountBehaviorCodelets() { - if (behaviorCodelets != null) { - for (BehaviorCodelet behaviorCodelet : behaviorCodelets) { - if (behaviorCodelet != null && behaviorCodelet.getId() != null - && behaviorCodelet.getMotivationalCodeletsIds() != null - && behaviorCodelet.getPerceptualCodeletsIds() != null) { - /* - * Outputs - */ - behaviorCodelet.addOutput(actionSequencePlanMemoryContainer); - behaviorCodelet.addOutput(actionSequencePlanRequestMemoryContainer); - /* - * Inputs - */ - if (motivationalCodelets != null) { - for (MotivationalCodelet motivationalCodelet : motivationalCodelets) { - if (motivationalCodelet != null && motivationalCodelet.getId() != null) { - ArrayList motivationalCodeletsIds = behaviorCodelet.getMotivationalCodeletsIds(); - if (motivationalCodeletsIds != null) { - for (String motivationalCodeletId : motivationalCodeletsIds) { - if (motivationalCodeletId != null && motivationalCodelet.getId().equalsIgnoreCase(motivationalCodeletId)) { - behaviorCodelet.addInputs(motivationalCodelet.getOutputs()); - } - } - } - } - } - } - if(perceptualCodelets != null) { - for(PerceptualCodelet perceptualCodelet : perceptualCodelets) { - if(perceptualCodelet != null && perceptualCodelet.getId() != null) { - ArrayList perceptualCodeletsIds = behaviorCodelet.getPerceptualCodeletsIds(); - if(perceptualCodeletsIds != null) { - for(String perceptualCodeletId : perceptualCodeletsIds) { - if(perceptualCodeletId != null && perceptualCodelet.getId().equalsIgnoreCase(perceptualCodeletId)) { - behaviorCodelet.addInputs(perceptualCodelet.getOutputs()); - } - } - } - } - } - } - if (soarCodelet != null && soarCodelet.getId() != null && behaviorCodelet.getSoarCodeletId() != null) { - if (soarCodelet.getId().equalsIgnoreCase(behaviorCodelet.getSoarCodeletId())) { - behaviorCodelet.addBroadcasts(soarCodelet.getOutputs()); - } - } - insertCodelet(behaviorCodelet); - } - } - } - } - - private void mountActionFromPerceptionCodelets() { - if (actionFromPerceptionCodelets != null) { - for (ActionFromPerceptionCodelet actionCodelet : actionFromPerceptionCodelets) { - if (actionCodelet != null && actionCodelet.getId() != null - && actionCodelet.getPerceptualCodeletsIds() != null - && actionCodelet.getMotivationalCodeletsIds() != null - && actionCodelet.getMotorCodeletId() != null) { - insertCodelet(actionCodelet); - /* - * Outputs - */ - if (motorCodelets != null) { - for (IMotorCodelet motorCodelet : motorCodelets) { - if (motorCodelet != null && motorCodelet.getId() != null) { - if (motorCodelet.getId().equalsIgnoreCase(actionCodelet.getMotorCodeletId())) { - actionCodelet.addOutputs(motorCodelet.getInputs()); + } + + private void mountActivityTrackingCodelet() { + + if (activityTrackingCodelet != null && activityTrackingCodelet.getId() != null + && activityTrackingCodelet.getPerceptualCodeletsIds() != null) { + + /* + * Inputs + */ + activityTrackingCodelet.addInput(actionSequencePlanMemoryContainer); + + if(perceptualCodelets != null) { + for(PerceptualCodelet perceptualCodelet : perceptualCodelets) { + if(perceptualCodelet != null && perceptualCodelet.getId() != null) { + ArrayList perceptualCodeletsIds = activityTrackingCodelet.getPerceptualCodeletsIds(); + if(perceptualCodeletsIds != null) { + for(String perceptualCodeletId : perceptualCodeletsIds) { + if(perceptualCodeletId != null && perceptualCodelet.getId().equalsIgnoreCase(perceptualCodeletId)) { + activityTrackingCodelet.addInputs(perceptualCodelet.getOutputs()); + } + } + } + } } - } - } - } - /* - * Inputs - */ - if (motivationalCodelets != null) { - for (MotivationalCodelet motivationalCodelet : motivationalCodelets) { - if (motivationalCodelet != null && motivationalCodelet.getId() != null) { - ArrayList motivationalCodeletsIds = actionCodelet.getMotivationalCodeletsIds(); - if (motivationalCodeletsIds != null) { - for (String motivationalCodeletId : motivationalCodeletsIds) { - if (motivationalCodeletId != null && motivationalCodelet.getId().equalsIgnoreCase(motivationalCodeletId)) { - actionCodelet.addInputs(motivationalCodelet.getOutputs()); + } + insertCodelet(activityTrackingCodelet); + } + + } + + private void mountBehaviorCodelets() { + if (behaviorCodelets != null) { + for (BehaviorCodelet behaviorCodelet : behaviorCodelets) { + if (behaviorCodelet != null && behaviorCodelet.getId() != null + && behaviorCodelet.getMotivationalCodeletsIds() != null + && behaviorCodelet.getPerceptualCodeletsIds() != null) { + /* + * Outputs + */ + behaviorCodelet.addOutput(actionSequencePlanMemoryContainer); + behaviorCodelet.addOutput(actionSequencePlanRequestMemoryContainer); + /* + * Inputs + */ + if (motivationalCodelets != null) { + for (MotivationalCodelet motivationalCodelet : motivationalCodelets) { + if (motivationalCodelet != null && motivationalCodelet.getId() != null) { + ArrayList motivationalCodeletsIds = behaviorCodelet.getMotivationalCodeletsIds(); + if (motivationalCodeletsIds != null) { + for (String motivationalCodeletId : motivationalCodeletsIds) { + if (motivationalCodeletId != null && motivationalCodelet.getId().equalsIgnoreCase(motivationalCodeletId)) { + behaviorCodelet.addInputs(motivationalCodelet.getOutputs()); + } + } + } + } + } + } + if(perceptualCodelets != null) { + for(PerceptualCodelet perceptualCodelet : perceptualCodelets) { + if(perceptualCodelet != null && perceptualCodelet.getId() != null) { + ArrayList perceptualCodeletsIds = behaviorCodelet.getPerceptualCodeletsIds(); + if(perceptualCodeletsIds != null) { + for(String perceptualCodeletId : perceptualCodeletsIds) { + if(perceptualCodeletId != null && perceptualCodelet.getId().equalsIgnoreCase(perceptualCodeletId)) { + behaviorCodelet.addInputs(perceptualCodelet.getOutputs()); + } + } + } + } + } + } + if (soarCodelet != null && soarCodelet.getId() != null && behaviorCodelet.getSoarCodeletId() != null) { + if (soarCodelet.getId().equalsIgnoreCase(behaviorCodelet.getSoarCodeletId())) { + behaviorCodelet.addBroadcasts(soarCodelet.getOutputs()); + } } - } + insertCodelet(behaviorCodelet); } - } } - } - if (perceptualCodelets != null) { - for (PerceptualCodelet perceptualCodelet : perceptualCodelets) { - if (perceptualCodelet != null && perceptualCodelet.getId() != null) { - ArrayList perceptualCodeletsIds = actionCodelet.getPerceptualCodeletsIds(); - if (perceptualCodeletsIds != null) { - for (String perceptualCodeletId : perceptualCodeletsIds) { - if (perceptualCodeletId != null && perceptualCodelet.getId().equalsIgnoreCase(perceptualCodeletId)) { - actionCodelet.addInputs(perceptualCodelet.getOutputs()); + } + } + + private void mountActionFromPerceptionCodelets() { + if (actionFromPerceptionCodelets != null) { + for (ActionFromPerceptionCodelet actionCodelet : actionFromPerceptionCodelets) { + if (actionCodelet != null && actionCodelet.getId() != null + && actionCodelet.getPerceptualCodeletsIds() != null + && actionCodelet.getMotivationalCodeletsIds() != null + && actionCodelet.getMotorCodeletId() != null) { + insertCodelet(actionCodelet); + /* + * Outputs + */ + if (motorCodelets != null) { + for (IMotorCodelet motorCodelet : motorCodelets) { + if (motorCodelet != null && motorCodelet.getId() != null) { + if (motorCodelet.getId().equalsIgnoreCase(actionCodelet.getMotorCodeletId())) { + actionCodelet.addOutputs(motorCodelet.getInputs()); + } + } + } } - } - } - } + /* + * Inputs + */ + if (motivationalCodelets != null) { + for (MotivationalCodelet motivationalCodelet : motivationalCodelets) { + if (motivationalCodelet != null && motivationalCodelet.getId() != null) { + ArrayList motivationalCodeletsIds = actionCodelet.getMotivationalCodeletsIds(); + if (motivationalCodeletsIds != null) { + for (String motivationalCodeletId : motivationalCodeletsIds) { + if (motivationalCodeletId != null && motivationalCodelet.getId().equalsIgnoreCase(motivationalCodeletId)) { + actionCodelet.addInputs(motivationalCodelet.getOutputs()); + } + } + } + } + } + } + if (perceptualCodelets != null) { + for (PerceptualCodelet perceptualCodelet : perceptualCodelets) { + if (perceptualCodelet != null && perceptualCodelet.getId() != null) { + ArrayList perceptualCodeletsIds = actionCodelet.getPerceptualCodeletsIds(); + if (perceptualCodeletsIds != null) { + for (String perceptualCodeletId : perceptualCodeletsIds) { + if (perceptualCodeletId != null && perceptualCodelet.getId().equalsIgnoreCase(perceptualCodeletId)) { + actionCodelet.addInputs(perceptualCodelet.getOutputs()); + } + } + } + } + } + } + if (soarCodelet != null && soarCodelet.getId() != null && actionCodelet.getSoarCodeletId() != null) { + if (soarCodelet.getId().equalsIgnoreCase(actionCodelet.getSoarCodeletId())) { + actionCodelet.addBroadcasts(soarCodelet.getOutputs()); + } + } + } } - } - if (soarCodelet != null && soarCodelet.getId() != null && actionCodelet.getSoarCodeletId() != null) { - if (soarCodelet.getId().equalsIgnoreCase(actionCodelet.getSoarCodeletId())) { - actionCodelet.addBroadcasts(soarCodelet.getOutputs()); + } + } + + private void mountActionFromPlanningCodelets() { + if (actionFromPlanningCodelets != null) { + for (ActionFromPlanningCodelet actionCodelet : actionFromPlanningCodelets) { + if (actionCodelet != null && actionCodelet.getId() != null + && actionCodelet.getPerceptualCodeletsIds() != null + && actionCodelet.getMotorCodeletId() != null) { + insertCodelet(actionCodelet); + /* + * Outputs + */ + if (motorCodelets != null) { + for (IMotorCodelet motorCodelet : motorCodelets) { + if (motorCodelet != null && motorCodelet.getId() != null) { + if (motorCodelet.getId().equalsIgnoreCase(actionCodelet.getMotorCodeletId())) { + actionCodelet.addOutputs(motorCodelet.getInputs()); + } + } + } + } + /* + * Inputs + */ + if (perceptualCodelets != null) { + for (PerceptualCodelet perceptualCodelet : perceptualCodelets) { + if (perceptualCodelet != null && perceptualCodelet.getId() != null) { + ArrayList perceptualCodeletsIds = actionCodelet.getPerceptualCodeletsIds(); + if (perceptualCodeletsIds != null) { + for (String perceptualCodeletId : perceptualCodeletsIds) { + if (perceptualCodeletId != null && perceptualCodelet.getId().equalsIgnoreCase(perceptualCodeletId)) { + actionCodelet.addInputs(perceptualCodelet.getOutputs()); + } + } + } + } + } + } + if (soarCodelet != null && soarCodelet.getId() != null && actionCodelet.getSoarCodeletId() != null) { + if (soarCodelet.getId().equalsIgnoreCase(actionCodelet.getSoarCodeletId())) { + actionCodelet.addBroadcasts(soarCodelet.getOutputs()); + } + } + actionCodelet.addInput(actionSequencePlanMemoryContainer); + } } - } } - } - } - } - - private void mountActionFromPlanningCodelets() { - if (actionFromPlanningCodelets != null) { - for (ActionFromPlanningCodelet actionCodelet : actionFromPlanningCodelets) { - if (actionCodelet != null && actionCodelet.getId() != null - && actionCodelet.getPerceptualCodeletsIds() != null - && actionCodelet.getMotorCodeletId() != null) { - insertCodelet(actionCodelet); - /* - * Outputs - */ - if (motorCodelets != null) { + } + + private void mountMotorCodelets() { + if (motorCodelets != null) { for (IMotorCodelet motorCodelet : motorCodelets) { - if (motorCodelet != null && motorCodelet.getId() != null) { - if (motorCodelet.getId().equalsIgnoreCase(actionCodelet.getMotorCodeletId())) { - actionCodelet.addOutputs(motorCodelet.getInputs()); + if (motorCodelet != null && motorCodelet.getId() != null) { + insertCodelet((Codelet) motorCodelet); + /* + * Input + */ + Memory motorMemoryContainer = createMemoryContainer(motorCodelet.getId()); + motorCodelet.addInput(motorMemoryContainer); } - } } - } - /* - * Inputs - */ - if (perceptualCodelets != null) { - for (PerceptualCodelet perceptualCodelet : perceptualCodelets) { - if (perceptualCodelet != null && perceptualCodelet.getId() != null) { - ArrayList perceptualCodeletsIds = actionCodelet.getPerceptualCodeletsIds(); - if (perceptualCodeletsIds != null) { - for (String perceptualCodeletId : perceptualCodeletsIds) { - if (perceptualCodeletId != null && perceptualCodelet.getId().equalsIgnoreCase(perceptualCodeletId)) { - actionCodelet.addInputs(perceptualCodelet.getOutputs()); - } + } + } + + private void mountAttentionCodelets() { + if (attentionCodeletSystem1 != null) { + /* + * Inputs + */ + if (perceptualCodelets != null) { + for (String inputPerceptualId : attentionCodeletSystem1.getPerceptualCodeletsIds()) { + for (PerceptualCodelet perceptualCodelet : perceptualCodelets) { + if (inputPerceptualId.equals(perceptualCodelet.getId())) { + attentionCodeletSystem1.addInputs(perceptualCodelet.getOutputs()); + } } - } } - } - } - if (soarCodelet != null && soarCodelet.getId() != null && actionCodelet.getSoarCodeletId() != null) { - if (soarCodelet.getId().equalsIgnoreCase(actionCodelet.getSoarCodeletId())) { - actionCodelet.addBroadcasts(soarCodelet.getOutputs()); } - } - actionCodelet.addInput(actionSequencePlanMemoryContainer); + /* + * Outputs + */ + Memory attentionMemoryOutput = createMemoryObject(attentionCodeletSystem1.getId()); + attentionCodeletSystem1.addOutput(attentionMemoryOutput); + attentionCodeletSystem1.setOutputFilteredPerceptsMO(attentionMemoryOutput); + insertCodelet(attentionCodeletSystem1); } - } - } - } - - private void mountMotorCodelets() { - if (motorCodelets != null) { - for (IMotorCodelet motorCodelet : motorCodelets) { - if (motorCodelet != null && motorCodelet.getId() != null) { - insertCodelet((Codelet) motorCodelet); - /* - * Input - */ - Memory motorMemoryContainer = createMemoryContainer(motorCodelet.getId()); - motorCodelet.addInput(motorMemoryContainer); + } + + private void mountSoarCodelet() { + if (soarCodelet != null) { + soarCodelet.addInput(createMemoryObject(WorkingMemory.WORKING_MEMORY_INPUT, getWorkingMemory())); + soarCodelet.addOutput(createMemoryObject(soarCodelet.getId())); + insertCodelet(soarCodelet); } - } - } - } - - private void mountAttentionCodelets() { - if (attentionCodeletSystem1 != null) { - /* - * Inputs - */ - if (perceptualCodelets != null) { - for (String inputPerceptualId : attentionCodeletSystem1.getPerceptualCodeletsIds()) { - for (PerceptualCodelet perceptualCodelet : perceptualCodelets) { - if (inputPerceptualId.equals(perceptualCodelet.getId())) { - attentionCodeletSystem1.addInputs(perceptualCodelet.getOutputs()); + } + + private void mountWorkingMemory() { + if (getWorkingMemory() != null) { + if (attentionCodeletSystem1 != null) { + getWorkingMemory().setCurrentPerceptionMemory(attentionCodeletSystem1.getOutputFilteredPerceptsMO()); } - } } - } - /* - * Outputs - */ - Memory attentionMemoryOutput = createMemoryObject(attentionCodeletSystem1.getId()); - attentionCodeletSystem1.addOutput(attentionMemoryOutput); - attentionCodeletSystem1.setOutputFilteredPerceptsMO(attentionMemoryOutput); - insertCodelet(attentionCodeletSystem1); - } - } - - private void mountSoarCodelet() { - if (soarCodelet != null) { - soarCodelet.addInput(createMemoryObject(WorkingMemory.WORKING_MEMORY_INPUT, getWorkingMemory())); - soarCodelet.addOutput(createMemoryObject(soarCodelet.getId())); - insertCodelet(soarCodelet); - } - } - - private void mountWorkingMemory() { - if (getWorkingMemory() != null) { - if (attentionCodeletSystem1 != null) { - getWorkingMemory().setCurrentPerceptionMemory(attentionCodeletSystem1.getOutputFilteredPerceptsMO()); - } - } - } - - /** - * Sets the Sensory Codelets. - * - * @deprecated instead, add Sensory Codelets using the interface ISensoryCodelet - * - * @param sensoryCodelets - * the sensoryCodelets to set - */ - @Deprecated - public void setSensoryCodelets(List sensoryCodelets) { - this.sensoryCodelets = new ArrayList(); - this.sensoryCodelets.addAll(sensoryCodelets); - } - - /** - * Sets the Perceptual Codelets. - * - * @param perceptualCodelets - * the perceptualCodelets to set - */ - public void setPerceptualCodelets(List perceptualCodelets) { - this.perceptualCodelets = perceptualCodelets; - } - - /** - * Sets the Mood Codelets. - * - * @param moodCodelets - * the moodCodelets to set - */ - public void setMoodCodelets(List moodCodelets) { - this.moodCodelets = moodCodelets; - } - - /** - * Sets the Motivational Codelets. - * - * @param motivationalCodelets - * the motivationalCodelets to set - */ - public void setMotivationalCodelets(List motivationalCodelets) { - this.motivationalCodelets = motivationalCodelets; - } - - /** - * Sets the System 1 Attention Codelet. - * - * @param attentionCodeletSystem1 - * the attentionCodeletSystem1 to set - */ - public void setAttentionCodeletSystem1(AttentionCodelet attentionCodeletSystem1) { - this.attentionCodeletSystem1 = attentionCodeletSystem1; - } - - /** - * Sets the Emotional Codelets. - * - * @param emotionalCodelets - * the emotionalCodelets to set - */ - public void setEmotionalCodelets(List emotionalCodelets) { - this.emotionalCodelets = emotionalCodelets; - } - - /** - * Sets the Motor Codelets. - * - * @deprecated instead, add Motor Codelets using the interface IMotorCodelet - * @param motorCodelets - * the motorCodelets to set - */ - @Deprecated - public void setMotorCodelets(List motorCodelets) { - this.motorCodelets = new ArrayList(); - this.motorCodelets.addAll(motorCodelets); - } - - /** - * Sets the System 2 Attention Codelets - * - * @param attentionCodeletsSystem2 - * the attentionCodeletsSystem2 to set - */ - public void setAttentionCodeletsSystem2( - List attentionCodeletsSystem2) { - this.attentionCodeletsSystem2 = attentionCodeletsSystem2; - } - - /** - * Sets the Episodic Learning Codelet. - * - * @param episodicLearningCodelet - * the episodicLearningCodelet to set - */ - public void setEpisodicLearningCodelet(EpisodicLearningCodelet episodicLearningCodelet) { - this.episodicLearningCodelet = episodicLearningCodelet; - } - - /** - * Sets the Episodic Retrieval Codelet. - * - * @param episodicRetrievalCodelet - * the episodicRetrievalCodelet to set - */ - public void setEpisodicRetrievalCodelet(EpisodicRetrievalCodelet episodicRetrievalCodelet) { - this.episodicRetrievalCodelet = episodicRetrievalCodelet; - } - - /** - * Sets the Expectation Codelet. - * - * @param expectationCodelet - * the expectationCodelet to set - */ - public void setExpectationCodelet(ExpectationCodelet expectationCodelet) { - this.expectationCodelet = expectationCodelet; - } - - /** - * Sets the Consciousness Codelet. - * - * @param consciousnessCodelet - * the consciousnessCodelet to set - */ - public void setConsciousnessCodelet(ConsciousnessCodelet consciousnessCodelet) { - this.consciousnessCodelet = consciousnessCodelet; - } - - /** - * Sets the Soar Codelet. - * - * @param soarCodelet - * the soarCodelet to set - */ - public void setSoarCodelet(SoarCodelet soarCodelet) { - this.soarCodelet = soarCodelet; - } - - /** - * Sets the Goal Codelet. - * - * @param goalCodelet - * the goalCodelet to set - */ - public void setGoalCodelet(GoalCodelet goalCodelet) { - this.goalCodelet = goalCodelet; - } - - /** - * Sets the Appraisal Codelet. - * - * @param appraisalCodelet - * the appraisalCodelet to set - */ - public void setAppraisalCodelet(AppraisalCodelet appraisalCodelet) { - this.appraisalCodelet = appraisalCodelet; - } - - /** - * @param actionFromPlanningCodelets the actionFromPlanningCodelets to set - */ - public void setActionFromPlanningCodelets(List actionFromPlanningCodelets) { - this.actionFromPlanningCodelets = actionFromPlanningCodelets; - } - - /** - * @param actionFromPerceptionCodelets the actionFromPerceptionCodelets to set - */ - public void setActionFromPerceptionCodelets(List actionFromPerceptionCodelets) { - this.actionFromPerceptionCodelets = actionFromPerceptionCodelets; - } - - /** - * @param behaviorCodelets the behaviorCodelets to set - */ - public void setBehaviorCodelets(List behaviorCodelets) { - this.behaviorCodelets = behaviorCodelets; - } - - /** - * @param sensoryCodelets the sensoryCodelets to set - */ - public void setISensoryCodelets(List sensoryCodelets) { - this.sensoryCodelets = sensoryCodelets; - } - - /** - * @param motorCodelets the motorCodelets to set - */ - public void setIMotorCodelets(List motorCodelets) { - this.motorCodelets = motorCodelets; - } - - /** - * Gets the MECA Mind id - * - * @return the id - */ - public String getId() { - return id; - } - - /** - * Sets the MECA Mind id - * - * @param id - * the id to set. - */ - public void setId(String id) { - this.id = id; - } - - /** - * Gets the Mood Codelets. - * - * @return the mood codelets. - */ - public List getMoodCodelets() { - return moodCodelets; - } - - /** - * Gets the Motivational Codelets. - * - * @return the Motivational Codelets. - */ - public List getMotivationalCodelets() { - return motivationalCodelets; - } - - /** - * Gets the Emotional Codelets. - * - * @return the Emotional Codelets. - */ - public List getEmotionalCodelets() { - return emotionalCodelets; - } - - /** - * Gets the Goal Codelets. - * - * @return the Goal Codelet. - */ - public GoalCodelet getGoalCodelet() { - return goalCodelet; - } - - /** - * Gets the Appraisal Codelet. - * - * @return the Appraisal Codelet. - */ - public AppraisalCodelet getAppraisalCodelet() { - return appraisalCodelet; - } - - /** - * Gets the Working Memory. - * - * @return the Working Memory. - */ - public WorkingMemory getWorkingMemory() { - return workingMemory; - } - - /** - * Sets the Working Memory. - * - * @param workingMemory - * the working memory to set. - */ - public void setWorkingMemory(WorkingMemory workingMemory) { - this.workingMemory = workingMemory; - } - - /** - * Gets the Sensory Codelets. - * - * @return the sensoryCodelets. - */ - public List getSensoryCodelets() { - return sensoryCodelets; - } - - /** - * Gets the Perceptual Codelets. - * - * @return the perceptualCodelets. - */ - public List getPerceptualCodelets() { - return perceptualCodelets; - } - - /** - * Gets the Attention Codelet from System 1. - * - * @return the attentionCodeletSystem1. - */ - public AttentionCodelet getAttentionCodeletSystem1() { - return attentionCodeletSystem1; - } - - /** - * Gets the Motor Codelets. - * - * @return the motorCodelets. - */ - public List getMotorCodelets() { - return motorCodelets; - } - - /** - * Gets the Attention Codelets from System 2. - * - * @return the attentionCodeletsSystem2. - */ - public List getAttentionCodeletsSystem2() { - return attentionCodeletsSystem2; - } - - /** - * Gets the Episodic Learning Codelet. - * - * @return the episodicLearningCodelet. - */ - public EpisodicLearningCodelet getEpisodicLearningCodelet() { - return episodicLearningCodelet; - } - - /** - * Gets the Episodic Retrieval Codelet. - * - * @return the episodicRetrievalCodelet. - */ - public EpisodicRetrievalCodelet getEpisodicRetrievalCodelet() { - return episodicRetrievalCodelet; - } - - /** - * Gets the Expectation Codelet. - * - * @return the expectationCodelet. - */ - public ExpectationCodelet getExpectationCodelet() { - return expectationCodelet; - } - - /** - * Gets the Consciousness Codelet. - * - * @return the consciousnessCodelet. - */ - public ConsciousnessCodelet getConsciousnessCodelet() { - return consciousnessCodelet; - } - - /** - * Gets the Soar Codelet. - * - * @return the soarCodelet. - */ - public SoarCodelet getSoarCodelet() { - return soarCodelet; - } - - /** - * @return the behaviorCodelets - */ - public List getBehaviorCodelets() { - return behaviorCodelets; - } - - /** - * @return the actionFromPlanningCodelets - */ - public List getActionFromPlanningCodelets() { - return actionFromPlanningCodelets; - } - - /** - * @return the actionFromPerceptionCodelets - */ - public List getActionFromPerceptionCodelets() { - return actionFromPerceptionCodelets; - } + } + + /** + * Sets the Sensory Codelets. + * + * @deprecated instead, add Sensory Codelets using the interface ISensoryCodelet + * + * @param sensoryCodelets + * the sensoryCodelets to set + */ + @Deprecated + public void setSensoryCodelets(List sensoryCodelets) { + this.sensoryCodelets = new ArrayList(); + this.sensoryCodelets.addAll(sensoryCodelets); + } + + /** + * Sets the Perceptual Codelets. + * + * @param perceptualCodelets + * the perceptualCodelets to set + */ + public void setPerceptualCodelets(List perceptualCodelets) { + this.perceptualCodelets = perceptualCodelets; + } + + /** + * Sets the Mood Codelets. + * + * @param moodCodelets + * the moodCodelets to set + */ + public void setMoodCodelets(List moodCodelets) { + this.moodCodelets = moodCodelets; + } + + /** + * Sets the Motivational Codelets. + * + * @param motivationalCodelets + * the motivationalCodelets to set + */ + public void setMotivationalCodelets(List motivationalCodelets) { + this.motivationalCodelets = motivationalCodelets; + } + + /** + * Sets the System 1 Attention Codelet. + * + * @param attentionCodeletSystem1 + * the attentionCodeletSystem1 to set + */ + public void setAttentionCodeletSystem1(AttentionCodelet attentionCodeletSystem1) { + this.attentionCodeletSystem1 = attentionCodeletSystem1; + } + + /** + * Sets the Emotional Codelets. + * + * @param emotionalCodelets + * the emotionalCodelets to set + */ + public void setEmotionalCodelets(List emotionalCodelets) { + this.emotionalCodelets = emotionalCodelets; + } + + /** + * Sets the Motor Codelets. + * + * @deprecated instead, add Motor Codelets using the interface IMotorCodelet + * @param motorCodelets + * the motorCodelets to set + */ + @Deprecated + public void setMotorCodelets(List motorCodelets) { + this.motorCodelets = new ArrayList(); + this.motorCodelets.addAll(motorCodelets); + } + + /** + * Sets the System 2 Attention Codelets + * + * @param attentionCodeletsSystem2 + * the attentionCodeletsSystem2 to set + */ + public void setAttentionCodeletsSystem2( + List attentionCodeletsSystem2) { + this.attentionCodeletsSystem2 = attentionCodeletsSystem2; + } + + /** + * Sets the Episodic Learning Codelet. + * + * @param episodicLearningCodelet + * the episodicLearningCodelet to set + */ + public void setEpisodicLearningCodelet(EpisodicLearningCodelet episodicLearningCodelet) { + this.episodicLearningCodelet = episodicLearningCodelet; + } + + /** + * Sets the Episodic Retrieval Codelet. + * + * @param episodicRetrievalCodelet + * the episodicRetrievalCodelet to set + */ + public void setEpisodicRetrievalCodelet(EpisodicRetrievalCodelet episodicRetrievalCodelet) { + this.episodicRetrievalCodelet = episodicRetrievalCodelet; + } + + /** + * Sets the Expectation Codelet. + * + * @param expectationCodelet + * the expectationCodelet to set + */ + public void setExpectationCodelet(ExpectationCodelet expectationCodelet) { + this.expectationCodelet = expectationCodelet; + } + + /** + * Sets the Consciousness Codelet. + * + * @param consciousnessCodelet + * the consciousnessCodelet to set + */ + public void setConsciousnessCodelet(ConsciousnessCodelet consciousnessCodelet) { + this.consciousnessCodelet = consciousnessCodelet; + } + + /** + * Sets the Soar Codelet. + * + * @param soarCodelet + * the soarCodelet to set + */ + public void setSoarCodelet(SoarCodelet soarCodelet) { + this.soarCodelet = soarCodelet; + } + + /** + * Sets the Goal Codelet. + * + * @param goalCodelet + * the goalCodelet to set + */ + public void setGoalCodelet(GoalCodelet goalCodelet) { + this.goalCodelet = goalCodelet; + } + + /** + * Sets the Appraisal Codelet. + * + * @param appraisalCodelet + * the appraisalCodelet to set + */ + public void setAppraisalCodelet(AppraisalCodelet appraisalCodelet) { + this.appraisalCodelet = appraisalCodelet; + } + + /** + * @param actionFromPlanningCodelets the actionFromPlanningCodelets to set + */ + public void setActionFromPlanningCodelets(List actionFromPlanningCodelets) { + this.actionFromPlanningCodelets = actionFromPlanningCodelets; + } + + /** + * @param actionFromPerceptionCodelets the actionFromPerceptionCodelets to set + */ + public void setActionFromPerceptionCodelets(List actionFromPerceptionCodelets) { + this.actionFromPerceptionCodelets = actionFromPerceptionCodelets; + } + + /** + * @param behaviorCodelets the behaviorCodelets to set + */ + public void setBehaviorCodelets(List behaviorCodelets) { + this.behaviorCodelets = behaviorCodelets; + } + + /** + * @param sensoryCodelets the sensoryCodelets to set + */ + public void setISensoryCodelets(List sensoryCodelets) { + this.sensoryCodelets = sensoryCodelets; + } + + /** + * @param motorCodelets the motorCodelets to set + */ + public void setIMotorCodelets(List motorCodelets) { + this.motorCodelets = motorCodelets; + } + + /** + * Gets the MECA Mind id + * + * @return the id + */ + public String getId() { + return id; + } + + /** + * Sets the MECA Mind id + * + * @param id + * the id to set. + */ + public void setId(String id) { + this.id = id; + } + + /** + * Gets the Mood Codelets. + * + * @return the mood codelets. + */ + public List getMoodCodelets() { + return moodCodelets; + } + + /** + * Gets the Motivational Codelets. + * + * @return the Motivational Codelets. + */ + public List getMotivationalCodelets() { + return motivationalCodelets; + } + + /** + * Gets the Emotional Codelets. + * + * @return the Emotional Codelets. + */ + public List getEmotionalCodelets() { + return emotionalCodelets; + } + + /** + * Gets the Goal Codelets. + * + * @return the Goal Codelet. + */ + public GoalCodelet getGoalCodelet() { + return goalCodelet; + } + + /** + * Gets the Appraisal Codelet. + * + * @return the Appraisal Codelet. + */ + public AppraisalCodelet getAppraisalCodelet() { + return appraisalCodelet; + } + + /** + * Gets the Working Memory. + * + * @return the Working Memory. + */ + public WorkingMemory getWorkingMemory() { + return workingMemory; + } + + /** + * Sets the Working Memory. + * + * @param workingMemory + * the working memory to set. + */ + public void setWorkingMemory(WorkingMemory workingMemory) { + this.workingMemory = workingMemory; + } + + /** + * Gets the Sensory Codelets. + * + * @return the sensoryCodelets. + */ + public List getSensoryCodelets() { + return sensoryCodelets; + } + + /** + * Gets the Perceptual Codelets. + * + * @return the perceptualCodelets. + */ + public List getPerceptualCodelets() { + return perceptualCodelets; + } + + /** + * Gets the Attention Codelet from System 1. + * + * @return the attentionCodeletSystem1. + */ + public AttentionCodelet getAttentionCodeletSystem1() { + return attentionCodeletSystem1; + } + + /** + * Gets the Motor Codelets. + * + * @return the motorCodelets. + */ + public List getMotorCodelets() { + return motorCodelets; + } + + /** + * Gets the Attention Codelets from System 2. + * + * @return the attentionCodeletsSystem2. + */ + public List getAttentionCodeletsSystem2() { + return attentionCodeletsSystem2; + } + + /** + * Gets the Episodic Learning Codelet. + * + * @return the episodicLearningCodelet. + */ + public EpisodicLearningCodelet getEpisodicLearningCodelet() { + return episodicLearningCodelet; + } + + /** + * Gets the Episodic Retrieval Codelet. + * + * @return the episodicRetrievalCodelet. + */ + public EpisodicRetrievalCodelet getEpisodicRetrievalCodelet() { + return episodicRetrievalCodelet; + } + + /** + * Gets the Expectation Codelet. + * + * @return the expectationCodelet. + */ + public ExpectationCodelet getExpectationCodelet() { + return expectationCodelet; + } + + /** + * Gets the Consciousness Codelet. + * + * @return the consciousnessCodelet. + */ + public ConsciousnessCodelet getConsciousnessCodelet() { + return consciousnessCodelet; + } + + /** + * Gets the Soar Codelet. + * + * @return the soarCodelet. + */ + public SoarCodelet getSoarCodelet() { + return soarCodelet; + } + + /** + * @return the behaviorCodelets + */ + public List getBehaviorCodelets() { + return behaviorCodelets; + } + + /** + * @return the actionFromPlanningCodelets + */ + public List getActionFromPlanningCodelets() { + return actionFromPlanningCodelets; + } + + /** + * @return the actionFromPerceptionCodelets + */ + public List getActionFromPerceptionCodelets() { + return actionFromPerceptionCodelets; + } + + /** + * @return the activityTrackingCodelet + */ + public ActivityTrackingCodelet getActivityTrackingCodelet() { + return activityTrackingCodelet; + } + + /** + * @param activityTrackingCodelet the activityTrackingCodelet to set + */ + public void setActivityTrackingCodelet(ActivityTrackingCodelet activityTrackingCodelet) { + this.activityTrackingCodelet = activityTrackingCodelet; + } } diff --git a/src/main/java/br/unicamp/meca/system1/codelets/ActivityTrackingCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/ActivityTrackingCodelet.java new file mode 100644 index 0000000..f28da9e --- /dev/null +++ b/src/main/java/br/unicamp/meca/system1/codelets/ActivityTrackingCodelet.java @@ -0,0 +1,148 @@ +/** + * + */ +package br.unicamp.meca.system1.codelets; + +import java.util.ArrayList; + +import br.unicamp.cst.core.entities.Codelet; +import br.unicamp.cst.core.entities.Memory; +import br.unicamp.cst.core.exceptions.CodeletActivationBoundsException; +import br.unicamp.meca.mind.MecaMind; +import br.unicamp.meca.models.ActionSequencePlan; + +/** + * This class represents the MECA Activity Tracking Codelet. This + * Activity Tracking Codelet allows inputs from one or more of the Perceptual Codelets. The idea behind + * this codelet is to track the steps of an Action Sequence Plan in System 1. + *

+ * Usually, Activity Tracking Codelets are application-specific, and the + * MECA software implementation just provides basic template class, which is a + * wrapper to CST's {@link Codelet}, to be reused while building an application + * using MECA. + * + * @author A. L. O. Paraense + * + */ +public abstract class ActivityTrackingCodelet extends Codelet { + + protected String id; + + protected ArrayList perceptualCodeletsIds; + protected ArrayList perceptualMemories; + + protected Memory actionSequencePlanMemoryContainer; + + protected ActionSequencePlan actionSequencePlan; + + /** + * Creates a MECA Activity Tracking Codelet. + * + * @param id + * the id of the Activity Tracking. Must be unique + * per Activity Tracking. + * @param perceptualCodeletsIds + * the list of ids of the Perceptual Codelets whose outputs + * will be read by this Activity Tracking. + * @see Codelet + * @see ActionSequencePlan + */ + public ActivityTrackingCodelet(String id, ArrayList perceptualCodeletsIds) { + super(); + setName(id); + this.id = id; + this.perceptualCodeletsIds = perceptualCodeletsIds; + } + + @Override + public void accessMemoryObjects() { + int index=0; + + if(perceptualMemories == null || perceptualMemories.size() == 0) { + + perceptualMemories = new ArrayList<>(); + + if(perceptualCodeletsIds != null) { + + for(String perceptualCodeletId : perceptualCodeletsIds) { + Memory perceptualMemory = this.getInput(perceptualCodeletId, index); + perceptualMemories.add(perceptualMemory); + } + } + } + + if(actionSequencePlanMemoryContainer == null) + actionSequencePlanMemoryContainer = this.getOutput(MecaMind.ACTION_SEQUENCE_PLAN_ID, index); + + } + + @Override + public void calculateActivation() { + try { + setActivation(0.0d); + } catch (CodeletActivationBoundsException e) { + e.printStackTrace(); + } + } + + /** + * Track and advance actions in the sequence plan. + * + * @param actionSequencePlan + * the ActionSequencePlan. + * @param perceptualMemories + * the list Perceptual Memories coming from Perceptual Codelets. + */ + public abstract void trackActionSequencePlan(ArrayList perceptualMemories, ActionSequencePlan actionSequencePlan); + + + @Override + public void proc() { + + actionSequencePlan = (ActionSequencePlan) actionSequencePlanMemoryContainer.getI(); + + trackActionSequencePlan(perceptualMemories, actionSequencePlan); + } + + /** + * @return the id + */ + public String getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(String id) { + this.id = id; + } + + /** + * @return the perceptualCodeletsIds + */ + public ArrayList getPerceptualCodeletsIds() { + return perceptualCodeletsIds; + } + + /** + * @param perceptualCodeletsIds the perceptualCodeletsIds to set + */ + public void setPerceptualCodeletsIds(ArrayList perceptualCodeletsIds) { + this.perceptualCodeletsIds = perceptualCodeletsIds; + } + + /** + * @return the actionSequencePlanMemoryContainer + */ + public Memory getActionSequencePlanMemoryContainer() { + return actionSequencePlanMemoryContainer; + } + + /** + * @param actionSequencePlanMemoryContainer the actionSequencePlanMemoryContainer to set + */ + public void setActionSequencePlanMemoryContainer(Memory actionSequencePlanMemoryContainer) { + this.actionSequencePlanMemoryContainer = actionSequencePlanMemoryContainer; + } +} From 21e0d74556eb7e0e42171cc26a220f8401b28aaf Mon Sep 17 00:00:00 2001 From: Andre Paraense Date: Fri, 14 Aug 2020 19:11:01 +0100 Subject: [PATCH 16/89] Behavior refactoring --- .../system1/codelets/BehaviorCodelet.java | 33 +++++++++---------- .../br/unicamp/meca/mind/MecaMindTest.java | 26 ++++++++++++--- .../Test1AndTest2BehaviorCodelet.java | 19 +++++------ 3 files changed, 45 insertions(+), 33 deletions(-) diff --git a/src/main/java/br/unicamp/meca/system1/codelets/BehaviorCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/BehaviorCodelet.java index 366337a..a4e4914 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/BehaviorCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/BehaviorCodelet.java @@ -70,33 +70,18 @@ public abstract class BehaviorCodelet extends Codelet { * @param soarCodeletId * the id of the Soar Codelet whose outputs will be read by this * Behavior Codelet. - * @param actionSequencePlan - * the ActionSequencePlan that this Behavior Codelet will provide * @see Codelet - * @see ActionSequencePlan */ public BehaviorCodelet(String id, ArrayList perceptualCodeletsIds, ArrayList motivationalCodeletsIds, - String soarCodeletId, ActionSequencePlan actionSequencePlan) { + String soarCodeletId) { super(); setName(id); this.id = id; this.perceptualCodeletsIds = perceptualCodeletsIds; this.motivationalCodeletsIds = motivationalCodeletsIds; this.soarCodeletId = soarCodeletId; - this.actionSequencePlan = actionSequencePlan; } - - /** - * Track and advance actions in the sequence plan. To be implemented in each object of this class, - * according to its action sequence plan. - * - * @param actionSequencePlan - * the ActionSequencePlan that this Behavior Codelet provides. - * @param perceptualMemories - * the list Perceptual Memories coming from Perceptual Codelets. - */ - public abstract void trackActionSequencePlan(ArrayList perceptualMemories, ActionSequencePlan actionSequencePlan); - + @Override public void accessMemoryObjects() { @@ -172,10 +157,21 @@ public void calculateActivation() { } + /** + * Builds the action sequence plan to be outputed by this BehaviorCodelet + * + * @param perceptualMemories the Perceptual Memories coming from Perceptual Codelets. + * @return the action sequence plan to be followed. + */ + protected abstract ActionSequencePlan buildActionSequencePlan(ArrayList perceptualMemories); + @Override public void proc() { - trackActionSequencePlan(perceptualMemories,actionSequencePlan); + actionSequencePlan = buildActionSequencePlan(perceptualMemories); + + if(broadcastMemory != null && broadcastMemory.getI()!= null && broadcastMemory.getI() instanceof ActionSequencePlan) + actionSequencePlan = (ActionSequencePlan) broadcastMemory.getI(); if(actionSequencePlan != null) { ((MemoryContainer) actionSequencePlanMemoryContainer).setI(actionSequencePlan,getActivation(),id); @@ -186,6 +182,7 @@ public void proc() { } } + /** * Returns the id of the Soar Codelet whose outputs will be read by this * Behavior Codelet. diff --git a/src/test/java/br/unicamp/meca/mind/MecaMindTest.java b/src/test/java/br/unicamp/meca/mind/MecaMindTest.java index 4dbfde7..825c590 100644 --- a/src/test/java/br/unicamp/meca/mind/MecaMindTest.java +++ b/src/test/java/br/unicamp/meca/mind/MecaMindTest.java @@ -14,6 +14,7 @@ import org.junit.Test; import br.unicamp.cst.core.entities.Codelet; +import br.unicamp.cst.core.entities.Memory; import br.unicamp.cst.core.entities.MemoryContainer; import br.unicamp.cst.core.exceptions.CodeletActivationBoundsException; import br.unicamp.cst.util.MindViewer; @@ -31,6 +32,7 @@ import br.unicamp.meca.models.ActionStep; import br.unicamp.meca.system1.codelets.ActionFromPerceptionCodelet; import br.unicamp.meca.system1.codelets.ActionFromPlanningCodelet; +import br.unicamp.meca.system1.codelets.ActivityTrackingCodelet; import br.unicamp.meca.system1.codelets.BehaviorCodelet; import br.unicamp.meca.system1.codelets.IMotorCodelet; import br.unicamp.meca.system1.codelets.ISensoryCodelet; @@ -150,15 +152,28 @@ public static void setup() throws InterruptedException { Test2ActionFromPlanningCodelets test2ActionFromPlanningCodelets = new Test2ActionFromPlanningCodelets("Test2ActionFromPlanningCodelets", perceptualCodeletsIds, testMotorCodelet.getId(), null); actionFromPlanningCodelets.add(test2ActionFromPlanningCodelets); + + ActivityTrackingCodelet activityTrackingCodelet = new ActivityTrackingCodelet("ActivityTrackingCodelet", perceptualCodeletsIds) { + + @Override + public void trackActionSequencePlan(ArrayList perceptualMemories, ActionSequencePlan actionSequencePlan) { + + if(actionSequencePlan == null || actionSequencePlan.getActionStepSequence() == null) { + return; + } + + actionSequencePlan.setCurrentActionIdIndex(0); + + //In this test, will never go on to the second action. We could have limit on perceptual memory to move on, though. + } + }; List behaviorCodelets = new ArrayList<>(); - ActionStep as1 = new ActionStep("Test1ActionFromPlanningCodelet"); - ActionStep as2 = new ActionStep("Test2ActionFromPlanningCodelet"); - ActionSequencePlan test1Test2ActionSequence = new ActionSequencePlan(new ActionStep[] {as1,as2}); - - Test1AndTest2BehaviorCodelet test1AndTest2BehaviorCodelet = new Test1AndTest2BehaviorCodelet("Test1AndTest2BehaviorCodelet", perceptualCodeletsIds, testMotivationalFromPlanningCodeletIds, null, test1Test2ActionSequence); + Test1AndTest2BehaviorCodelet test1AndTest2BehaviorCodelet = new Test1AndTest2BehaviorCodelet("Test1AndTest2BehaviorCodelet", perceptualCodeletsIds, testMotivationalFromPlanningCodeletIds, null); behaviorCodelets.add(test1AndTest2BehaviorCodelet); + + /* * Inserting the System 1 codelets inside MECA mind @@ -170,6 +185,7 @@ public static void setup() throws InterruptedException { mecaMind.setActionFromPerceptionCodelets(actionFromPerceptionCodelets); mecaMind.setActionFromPlanningCodelets(actionFromPlanningCodelets); mecaMind.setBehaviorCodelets(behaviorCodelets); + mecaMind.setActivityTrackingCodelet(activityTrackingCodelet); /* * After passing references to the codelets, we call the method 'MecaMind.mountMecaMind()', which diff --git a/src/test/java/br/unicamp/meca/mind/behavior/Test1AndTest2BehaviorCodelet.java b/src/test/java/br/unicamp/meca/mind/behavior/Test1AndTest2BehaviorCodelet.java index 060f32e..3ed41ee 100644 --- a/src/test/java/br/unicamp/meca/mind/behavior/Test1AndTest2BehaviorCodelet.java +++ b/src/test/java/br/unicamp/meca/mind/behavior/Test1AndTest2BehaviorCodelet.java @@ -7,6 +7,7 @@ import br.unicamp.cst.core.entities.Memory; import br.unicamp.meca.models.ActionSequencePlan; +import br.unicamp.meca.models.ActionStep; import br.unicamp.meca.system1.codelets.BehaviorCodelet; /** @@ -16,20 +17,18 @@ public class Test1AndTest2BehaviorCodelet extends BehaviorCodelet { public Test1AndTest2BehaviorCodelet(String id, ArrayList perceptualCodeletsIds, - ArrayList motivationalCodeletsIds, String soarCodeletId, ActionSequencePlan actionSequencePlan) { - super(id, perceptualCodeletsIds, motivationalCodeletsIds, soarCodeletId, actionSequencePlan); + ArrayList motivationalCodeletsIds, String soarCodeletId) { + super(id, perceptualCodeletsIds, motivationalCodeletsIds, soarCodeletId); } @Override - public void trackActionSequencePlan(ArrayList perceptualMemories, ActionSequencePlan actionSequencePlan) { + protected ActionSequencePlan buildActionSequencePlan(ArrayList perceptualMemories) { - if(actionSequencePlan == null || actionSequencePlan.getActionStepSequence() == null) { - return; - } - - actionSequencePlan.setCurrentActionIdIndex(0); - - //In this test, will never go on to the second action. We could have limit on perceptual memory to move on, though. + ActionStep as1 = new ActionStep("Test1ActionFromPlanningCodelet"); + ActionStep as2 = new ActionStep("Test2ActionFromPlanningCodelet"); + ActionSequencePlan test1Test2ActionSequence = new ActionSequencePlan(new ActionStep[] {as1,as2}); + + return test1Test2ActionSequence; } } From e915ddfa36ce01eeeeb7fbb64ddd755a1dc27f61 Mon Sep 17 00:00:00 2001 From: Ricardo Gudwin Date: Thu, 20 Aug 2020 16:02:18 -0300 Subject: [PATCH 17/89] Many changes to enhance the ActivityTrackingCodelet system --- build.gradle | 4 +- .../java/br/unicamp/meca/mind/MecaMind.java | 62 +++++++++++++------ .../br/unicamp/meca/models/ActionStep.java | 6 +- .../codelets/ActionFromPerceptionCodelet.java | 2 +- .../codelets/ActivityTrackingCodelet.java | 34 ++++++---- .../system1/codelets/BehaviorCodelet.java | 2 +- .../system1/codelets/MotivationalCodelet.java | 4 +- .../Test1AndTest2BehaviorCodelet.java | 5 +- .../meca/models/ActionSequencePlanTest.java | 4 +- .../unicamp/meca/models/ActionStepTest.java | 21 +++++-- 10 files changed, 99 insertions(+), 45 deletions(-) diff --git a/build.gradle b/build.gradle index a839cf7..24f8a88 100644 --- a/build.gradle +++ b/build.gradle @@ -30,8 +30,8 @@ repositories { } dependencies { - api 'com.github.CST-Group:cst:0.5.1' - //api ':cst:0.5.1-full' + //api 'com.github.CST-Group:cst:0.5.1' + api ':cst:0.5.1-full' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' testImplementation 'org.ros.rosjava_messages:rosjava_test_msgs:0.3.0' diff --git a/src/main/java/br/unicamp/meca/mind/MecaMind.java b/src/main/java/br/unicamp/meca/mind/MecaMind.java index fe96978..9fbcec7 100644 --- a/src/main/java/br/unicamp/meca/mind/MecaMind.java +++ b/src/main/java/br/unicamp/meca/mind/MecaMind.java @@ -54,8 +54,8 @@ */ public class MecaMind extends Mind { - public static final String ACTION_SEQUENCE_PLAN_ID = "ACTION_SEQUENCE_PLAN_ID"; - public static final String ACTION_SEQUENCE_PLAN_REQUEST_ID = "ACTION_SEQUENCE_PLAN_REQUEST_ID"; + public static final String ACTION_SEQUENCE_PLAN_ID = "ExecutivePlan"; + public static final String ACTION_SEQUENCE_PLAN_REQUEST_ID = "PlanRequest"; /* * System 1 @@ -97,6 +97,19 @@ public class MecaMind extends Mind { public MecaMind() { setId(UUID.randomUUID().toString()); setWorkingMemory(new WorkingMemory(getId())); + createCodeletGroup("Sensory"); + createCodeletGroup("Motor"); + createCodeletGroup("Perception"); + createCodeletGroup("ActionFromPerception"); + createCodeletGroup("ActionFromPlanning"); + createCodeletGroup("Motivational"); + createCodeletGroup("Behavioral"); + createCodeletGroup("ActivityTracking"); + createMemoryGroup("Sensors"); + createMemoryGroup("Actuators"); + createMemoryGroup("Percepts"); + createMemoryGroup("Drives"); + createMemoryGroup("Plans"); } /** @@ -108,6 +121,19 @@ public MecaMind() { public MecaMind(String id) { setId(id); setWorkingMemory(new WorkingMemory(getId())); + createCodeletGroup("Sensory"); + createCodeletGroup("Motor"); + createCodeletGroup("Perception"); + createCodeletGroup("ActionFromPerception"); + createCodeletGroup("ActionFromPlanning"); + createCodeletGroup("Motivational"); + createCodeletGroup("Behavioral"); + createCodeletGroup("ActivityTracking"); + createMemoryGroup("Sensors"); + createMemoryGroup("Actuators"); + createMemoryGroup("Percepts"); + createMemoryGroup("Drives"); + createMemoryGroup("Plans"); } /** @@ -141,13 +167,6 @@ private void mountActionSequencePlanMemory() { } private void mountModules() { - // if (getMotivationalCodelets() != null) { - // if (getMotivationalCodelets().size() > 0) { - // List mtcodelets = getMotivationalCodelets(); - //// getMotivationalSubsystemModule() - //// .setMotivationalCodelets((List) mtcodelets); - // } - // } if (getSoarCodelet() != null) { getPlansSubsystemModule().setjSoarCodelet(getSoarCodelet()); } @@ -238,7 +257,7 @@ private void mountMotivationalCodelets() { /* * Output Drives */ - MemoryObject outputDrive = this.createMemoryObject(motivationalCodelet.getId() + "_DRIVE_MO"); + MemoryObject outputDrive = this.createMemoryObject(motivationalCodelet.getId() + "Drive"); motivationalCodelet.addOutput(outputDrive); insertCodelet(motivationalCodelet); } @@ -246,16 +265,23 @@ private void mountMotivationalCodelets() { } private void mountActivityTrackingCodelet() { - - if (activityTrackingCodelet != null && activityTrackingCodelet.getId() != null + + ArrayList perceptualIds = new ArrayList<>(); + for (PerceptualCodelet perception : perceptualCodelets) + perceptualIds.add(perception.getId()); + activityTrackingCodelet = new ActivityTrackingCodelet("ActivityTracking", perceptualIds); + registerCodelet(activityTrackingCodelet, "ActivityTracking"); + registerMemory(ACTION_SEQUENCE_PLAN_ID,"Plans"); + registerMemory(ACTION_SEQUENCE_PLAN_REQUEST_ID,"Plans"); + + if (activityTrackingCodelet != null && activityTrackingCodelet.getId() != null && activityTrackingCodelet.getPerceptualCodeletsIds() != null) { + /* + * Inputs + */ + activityTrackingCodelet.addInput(actionSequencePlanMemoryContainer); - /* - * Inputs - */ - activityTrackingCodelet.addInput(actionSequencePlanMemoryContainer); - - if(perceptualCodelets != null) { + if(perceptualCodelets != null) { for(PerceptualCodelet perceptualCodelet : perceptualCodelets) { if(perceptualCodelet != null && perceptualCodelet.getId() != null) { ArrayList perceptualCodeletsIds = activityTrackingCodelet.getPerceptualCodeletsIds(); diff --git a/src/main/java/br/unicamp/meca/models/ActionStep.java b/src/main/java/br/unicamp/meca/models/ActionStep.java index 08e90d3..7f89df2 100644 --- a/src/main/java/br/unicamp/meca/models/ActionStep.java +++ b/src/main/java/br/unicamp/meca/models/ActionStep.java @@ -12,14 +12,16 @@ ******************************************************************************/ package br.unicamp.meca.models; +import br.unicamp.cst.core.entities.Memory; import java.util.HashMap; +import java.util.List; import java.util.Map; /** * * @author rgudwin */ -public class ActionStep { +public abstract class ActionStep { String actionId; Map parameters; @@ -76,4 +78,6 @@ public void unsetParameter(String param) { parameters.remove(param); } + public abstract boolean stopCondition(List perception); + } diff --git a/src/main/java/br/unicamp/meca/system1/codelets/ActionFromPerceptionCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/ActionFromPerceptionCodelet.java index 2223336..5e83631 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/ActionFromPerceptionCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/ActionFromPerceptionCodelet.java @@ -106,7 +106,7 @@ public void accessMemoryObjects() { for(String motivationalCodeletsId : motivationalCodeletsIds) { - Memory inputDrive = this.getInput(motivationalCodeletsId + "_DRIVE_MO"); + Memory inputDrive = this.getInput(motivationalCodeletsId + "Drive"); driveMemories.add(inputDrive); } } diff --git a/src/main/java/br/unicamp/meca/system1/codelets/ActivityTrackingCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/ActivityTrackingCodelet.java index f28da9e..62e4cbf 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/ActivityTrackingCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/ActivityTrackingCodelet.java @@ -10,6 +10,7 @@ import br.unicamp.cst.core.exceptions.CodeletActivationBoundsException; import br.unicamp.meca.mind.MecaMind; import br.unicamp.meca.models.ActionSequencePlan; +import br.unicamp.meca.models.ActionStep; /** * This class represents the MECA Activity Tracking Codelet. This @@ -24,7 +25,7 @@ * @author A. L. O. Paraense * */ -public abstract class ActivityTrackingCodelet extends Codelet { +public class ActivityTrackingCodelet extends Codelet { protected String id; @@ -72,7 +73,7 @@ public void accessMemoryObjects() { } if(actionSequencePlanMemoryContainer == null) - actionSequencePlanMemoryContainer = this.getOutput(MecaMind.ACTION_SEQUENCE_PLAN_ID, index); + actionSequencePlanMemoryContainer = this.getInput(MecaMind.ACTION_SEQUENCE_PLAN_ID, index); } @@ -85,17 +86,26 @@ public void calculateActivation() { } } - /** - * Track and advance actions in the sequence plan. - * - * @param actionSequencePlan - * the ActionSequencePlan. - * @param perceptualMemories - * the list Perceptual Memories coming from Perceptual Codelets. - */ - public abstract void trackActionSequencePlan(ArrayList perceptualMemories, ActionSequencePlan actionSequencePlan); + /** + * Track and advance actions in the sequence plan. + * + * @param actionSequencePlan + * the ActionSequencePlan. + * @param perceptualMemories + * the list Perceptual Memories coming from Perceptual Codelets. + */ + public void trackActionSequencePlan(ArrayList perceptualMemories, ActionSequencePlan actionSequencePlan) { + if(actionSequencePlan != null && + actionSequencePlan.getActionStepSequence() != null && + perceptualMemories != null && + perceptualMemories.size() > 0) { + ActionStep currentActionStep = actionSequencePlan.getCurrentActionStep(); + if (currentActionStep.stopCondition(perceptualMemories)) { + actionSequencePlan.gotoNextAction(); + } + } + } - @Override public void proc() { diff --git a/src/main/java/br/unicamp/meca/system1/codelets/BehaviorCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/BehaviorCodelet.java index a4e4914..928dd76 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/BehaviorCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/BehaviorCodelet.java @@ -108,7 +108,7 @@ public void accessMemoryObjects() { for(String motivationalCodeletsId : motivationalCodeletsIds) { - Memory inputDrive = this.getInput(motivationalCodeletsId + "_DRIVE_MO"); + Memory inputDrive = this.getInput(motivationalCodeletsId + "Drive"); driveMemories.add(inputDrive); } } diff --git a/src/main/java/br/unicamp/meca/system1/codelets/MotivationalCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/MotivationalCodelet.java index ec55198..6307783 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/MotivationalCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/MotivationalCodelet.java @@ -73,14 +73,14 @@ public void accessMemoryObjects() { if (getSensoryVariables().size() == 0) { for (Memory sensoryMO : getInputs()) { - if (!sensoryMO.getName().contains("DRIVE")) + if (!sensoryMO.getName().contains("Drive")) getSensoryVariables().add(sensoryMO); } } if (getDrivesRelevance().size() == 0) { for (Memory driveMO : getInputs()) { - if (driveMO.getName().contains("DRIVE")) { + if (driveMO.getName().contains("Drive")) { getDrivesRelevance().putAll((Map) driveMO.getI()); } } diff --git a/src/test/java/br/unicamp/meca/mind/behavior/Test1AndTest2BehaviorCodelet.java b/src/test/java/br/unicamp/meca/mind/behavior/Test1AndTest2BehaviorCodelet.java index 3ed41ee..18e58ae 100644 --- a/src/test/java/br/unicamp/meca/mind/behavior/Test1AndTest2BehaviorCodelet.java +++ b/src/test/java/br/unicamp/meca/mind/behavior/Test1AndTest2BehaviorCodelet.java @@ -8,6 +8,7 @@ import br.unicamp.cst.core.entities.Memory; import br.unicamp.meca.models.ActionSequencePlan; import br.unicamp.meca.models.ActionStep; +import br.unicamp.meca.models.ActionStepTest; import br.unicamp.meca.system1.codelets.BehaviorCodelet; /** @@ -24,8 +25,8 @@ public Test1AndTest2BehaviorCodelet(String id, ArrayList perceptualCodel @Override protected ActionSequencePlan buildActionSequencePlan(ArrayList perceptualMemories) { - ActionStep as1 = new ActionStep("Test1ActionFromPlanningCodelet"); - ActionStep as2 = new ActionStep("Test2ActionFromPlanningCodelet"); + ActionStep as1 = new ActionStepTest("Test1ActionFromPlanningCodelet"); + ActionStep as2 = new ActionStepTest("Test2ActionFromPlanningCodelet"); ActionSequencePlan test1Test2ActionSequence = new ActionSequencePlan(new ActionStep[] {as1,as2}); return test1Test2ActionSequence; diff --git a/src/test/java/br/unicamp/meca/models/ActionSequencePlanTest.java b/src/test/java/br/unicamp/meca/models/ActionSequencePlanTest.java index 5b9de13..971d874 100644 --- a/src/test/java/br/unicamp/meca/models/ActionSequencePlanTest.java +++ b/src/test/java/br/unicamp/meca/models/ActionSequencePlanTest.java @@ -20,8 +20,8 @@ public void setUp() { @Test public void testGetCurrentActionId() { - ActionStep as1 = new ActionStep("Land"); - ActionStep as2 = new ActionStep("Stop"); + ActionStep as1 = new ActionStepTest("Land"); + ActionStep as2 = new ActionStepTest("Stop"); ActionSequencePlan landAndStopSequencePlan = new ActionSequencePlan(new ActionStep[] {as1,as2}); assertEquals(landAndStopSequencePlan.getCurrentActionStep().getActionId(), "Land"); diff --git a/src/test/java/br/unicamp/meca/models/ActionStepTest.java b/src/test/java/br/unicamp/meca/models/ActionStepTest.java index c0baf83..f4041a6 100644 --- a/src/test/java/br/unicamp/meca/models/ActionStepTest.java +++ b/src/test/java/br/unicamp/meca/models/ActionStepTest.java @@ -4,7 +4,8 @@ * and open the template in the editor. */ package br.unicamp.meca.models; -import java.util.logging.Logger; +import br.unicamp.cst.core.entities.Memory; +import java.util.List; import static org.junit.Assert.assertEquals; import org.junit.Test; @@ -12,18 +13,30 @@ * * @author rgudwin */ -public class ActionStepTest { +public class ActionStepTest extends ActionStep { + public ActionStepTest() { + + } + + public ActionStepTest(String s) { + super(s); + } public void setUp() { System.out.println("########## ActionStep TESTS ##########"); } + + @Override + public boolean stopCondition(List perceptions) { + return(true); + } @Test public void testActionStep() { - ActionStep as1 = new ActionStep(); + ActionStep as1 = new ActionStepTest(); assertEquals(as1.getNumberOfParameters(),0); - ActionStep as2 = new ActionStep("TestAction"); + ActionStep as2 = new ActionStepTest("TestAction"); assertEquals(as2.getNumberOfParameters(),0); assertEquals(as2.getActionId(),"TestAction"); as2.setParameter("param", "value"); From 6170accc6209f483719e9b915cccbbed1949984a Mon Sep 17 00:00:00 2001 From: Ricardo Gudwin Date: Mon, 24 Aug 2020 12:11:29 -0300 Subject: [PATCH 18/89] Many changes to enhance the ActivityTrackingCodelet system --- .../br/unicamp/meca/models/ActionSequencePlan.java | 13 +++++++++++++ .../java/br/unicamp/meca/models/ActionStep.java | 4 ++++ 2 files changed, 17 insertions(+) diff --git a/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java b/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java index dda7c3b..0b41c19 100644 --- a/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java +++ b/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java @@ -84,4 +84,17 @@ public void gotoNextAction() { if (currentActionIdIndex < actionIdSequence.length-1) currentActionIdIndex++; } + + public String toString() { + String output = "{ "; + int i=0; + for (ActionStep a : actionIdSequence) { + output += a.toString(); + i++; + if (i < actionIdSequence.length) + output += ", "; + } + output += "}"; + return(output); + } } diff --git a/src/main/java/br/unicamp/meca/models/ActionStep.java b/src/main/java/br/unicamp/meca/models/ActionStep.java index 7f89df2..1dcb37d 100644 --- a/src/main/java/br/unicamp/meca/models/ActionStep.java +++ b/src/main/java/br/unicamp/meca/models/ActionStep.java @@ -78,6 +78,10 @@ public void unsetParameter(String param) { parameters.remove(param); } + public String toString() { + return(actionId); + } + public abstract boolean stopCondition(List perception); } From fe8f6b2252a17d5ddad2352f48fd157568a560ee Mon Sep 17 00:00:00 2001 From: Andre Paraense Date: Thu, 3 Sep 2020 13:59:43 +0100 Subject: [PATCH 19/89] Merging ActionFromPerceptionCodelet and ActionFromPlanningCodelet into ActivityCodelet --- build.gradle | 4 +- .../java/br/unicamp/meca/mind/MecaMind.java | 137 +++------- .../meca/models/ActionSequencePlan.java | 4 +- .../codelets/ActionFromPlanningCodelet.java | 238 ------------------ ...ptionCodelet.java => ActivityCodelet.java} | 114 +++++---- .../br/unicamp/meca/mind/MecaMindTest.java | 218 +++++++++------- .../Test1ActionFromPlanningCodelet.java | 39 --- ...Codelet.java => Test1ActivityCodelet.java} | 17 +- .../Test2ActionFromPlanningCodelets.java | 41 --- .../mind/action/Test2ActivityCodelet.java | 46 ++++ .../mind/action/Test3ActivityCodelet.java | 46 ++++ .../Test1AndTest2BehaviorCodelet.java | 14 +- .../unicamp/meca/models/ActionStepTest.java | 2 +- 13 files changed, 349 insertions(+), 571 deletions(-) delete mode 100644 src/main/java/br/unicamp/meca/system1/codelets/ActionFromPlanningCodelet.java rename src/main/java/br/unicamp/meca/system1/codelets/{ActionFromPerceptionCodelet.java => ActivityCodelet.java} (64%) delete mode 100644 src/test/java/br/unicamp/meca/mind/action/Test1ActionFromPlanningCodelet.java rename src/test/java/br/unicamp/meca/mind/action/{Test1ActionFromPerceptionCodelet.java => Test1ActivityCodelet.java} (64%) delete mode 100644 src/test/java/br/unicamp/meca/mind/action/Test2ActionFromPlanningCodelets.java create mode 100644 src/test/java/br/unicamp/meca/mind/action/Test2ActivityCodelet.java create mode 100644 src/test/java/br/unicamp/meca/mind/action/Test3ActivityCodelet.java diff --git a/build.gradle b/build.gradle index 24f8a88..672f931 100644 --- a/build.gradle +++ b/build.gradle @@ -30,8 +30,8 @@ repositories { } dependencies { - //api 'com.github.CST-Group:cst:0.5.1' - api ':cst:0.5.1-full' + api 'com.github.CST-Group:cst:5e79d5e4271d82193dda0e2826fef43d13b9f100' + // api ':cst:0.5.1-full' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' testImplementation 'org.ros.rosjava_messages:rosjava_test_msgs:0.3.0' diff --git a/src/main/java/br/unicamp/meca/mind/MecaMind.java b/src/main/java/br/unicamp/meca/mind/MecaMind.java index 9fbcec7..53b2702 100644 --- a/src/main/java/br/unicamp/meca/mind/MecaMind.java +++ b/src/main/java/br/unicamp/meca/mind/MecaMind.java @@ -23,8 +23,7 @@ import br.unicamp.cst.core.entities.MemoryObject; import br.unicamp.cst.core.entities.Mind; import br.unicamp.meca.memory.WorkingMemory; -import br.unicamp.meca.system1.codelets.ActionFromPerceptionCodelet; -import br.unicamp.meca.system1.codelets.ActionFromPlanningCodelet; +import br.unicamp.meca.system1.codelets.ActivityCodelet; import br.unicamp.meca.system1.codelets.ActivityTrackingCodelet; import br.unicamp.meca.system1.codelets.AttentionCodelet; import br.unicamp.meca.system1.codelets.BehaviorCodelet; @@ -67,8 +66,7 @@ public class MecaMind extends Mind { private List motivationalCodelets; private AttentionCodelet attentionCodeletSystem1; private List emotionalCodelets; - private List actionFromPlanningCodelets; - private List actionFromPerceptionCodelets; + private List activityCodelets; private List behaviorCodelets; private List motorCodelets; private Memory actionSequencePlanMemoryContainer; @@ -100,8 +98,7 @@ public MecaMind() { createCodeletGroup("Sensory"); createCodeletGroup("Motor"); createCodeletGroup("Perception"); - createCodeletGroup("ActionFromPerception"); - createCodeletGroup("ActionFromPlanning"); + createCodeletGroup("Activity"); createCodeletGroup("Motivational"); createCodeletGroup("Behavioral"); createCodeletGroup("ActivityTracking"); @@ -124,8 +121,7 @@ public MecaMind(String id) { createCodeletGroup("Sensory"); createCodeletGroup("Motor"); createCodeletGroup("Perception"); - createCodeletGroup("ActionFromPerception"); - createCodeletGroup("ActionFromPlanning"); + createCodeletGroup("Activity"); createCodeletGroup("Motivational"); createCodeletGroup("Behavioral"); createCodeletGroup("ActivityTracking"); @@ -156,8 +152,7 @@ public void mountMecaMind() { mountActionSequencePlanMemory(); mountBehaviorCodelets(); mountActivityTrackingCodelet(); - mountActionFromPlanningCodelets(); - mountActionFromPerceptionCodelets(); + mountActivityCodelets(); mountModules(); } @@ -352,23 +347,23 @@ private void mountBehaviorCodelets() { } } } - - private void mountActionFromPerceptionCodelets() { - if (actionFromPerceptionCodelets != null) { - for (ActionFromPerceptionCodelet actionCodelet : actionFromPerceptionCodelets) { - if (actionCodelet != null && actionCodelet.getId() != null - && actionCodelet.getPerceptualCodeletsIds() != null - && actionCodelet.getMotivationalCodeletsIds() != null - && actionCodelet.getMotorCodeletId() != null) { - insertCodelet(actionCodelet); + + private void mountActivityCodelets() { + if (activityCodelets != null) { + for (ActivityCodelet activityCodelet : activityCodelets) { + if (activityCodelet != null && activityCodelet.getId() != null + && activityCodelet.getPerceptualCodeletsIds() != null + && activityCodelet.getMotivationalCodeletsIds() != null + && activityCodelet.getMotorCodeletId() != null) { + insertCodelet(activityCodelet); /* * Outputs */ if (motorCodelets != null) { for (IMotorCodelet motorCodelet : motorCodelets) { if (motorCodelet != null && motorCodelet.getId() != null) { - if (motorCodelet.getId().equalsIgnoreCase(actionCodelet.getMotorCodeletId())) { - actionCodelet.addOutputs(motorCodelet.getInputs()); + if (motorCodelet.getId().equalsIgnoreCase(activityCodelet.getMotorCodeletId())) { + activityCodelet.addOutputs(motorCodelet.getInputs()); } } } @@ -379,11 +374,11 @@ private void mountActionFromPerceptionCodelets() { if (motivationalCodelets != null) { for (MotivationalCodelet motivationalCodelet : motivationalCodelets) { if (motivationalCodelet != null && motivationalCodelet.getId() != null) { - ArrayList motivationalCodeletsIds = actionCodelet.getMotivationalCodeletsIds(); + ArrayList motivationalCodeletsIds = activityCodelet.getMotivationalCodeletsIds(); if (motivationalCodeletsIds != null) { for (String motivationalCodeletId : motivationalCodeletsIds) { if (motivationalCodeletId != null && motivationalCodelet.getId().equalsIgnoreCase(motivationalCodeletId)) { - actionCodelet.addInputs(motivationalCodelet.getOutputs()); + activityCodelet.addInputs(motivationalCodelet.getOutputs()); } } } @@ -393,69 +388,23 @@ private void mountActionFromPerceptionCodelets() { if (perceptualCodelets != null) { for (PerceptualCodelet perceptualCodelet : perceptualCodelets) { if (perceptualCodelet != null && perceptualCodelet.getId() != null) { - ArrayList perceptualCodeletsIds = actionCodelet.getPerceptualCodeletsIds(); + ArrayList perceptualCodeletsIds = activityCodelet.getPerceptualCodeletsIds(); if (perceptualCodeletsIds != null) { for (String perceptualCodeletId : perceptualCodeletsIds) { if (perceptualCodeletId != null && perceptualCodelet.getId().equalsIgnoreCase(perceptualCodeletId)) { - actionCodelet.addInputs(perceptualCodelet.getOutputs()); + activityCodelet.addInputs(perceptualCodelet.getOutputs()); } } } } } } - if (soarCodelet != null && soarCodelet.getId() != null && actionCodelet.getSoarCodeletId() != null) { - if (soarCodelet.getId().equalsIgnoreCase(actionCodelet.getSoarCodeletId())) { - actionCodelet.addBroadcasts(soarCodelet.getOutputs()); - } - } - } - } - } - } - - private void mountActionFromPlanningCodelets() { - if (actionFromPlanningCodelets != null) { - for (ActionFromPlanningCodelet actionCodelet : actionFromPlanningCodelets) { - if (actionCodelet != null && actionCodelet.getId() != null - && actionCodelet.getPerceptualCodeletsIds() != null - && actionCodelet.getMotorCodeletId() != null) { - insertCodelet(actionCodelet); - /* - * Outputs - */ - if (motorCodelets != null) { - for (IMotorCodelet motorCodelet : motorCodelets) { - if (motorCodelet != null && motorCodelet.getId() != null) { - if (motorCodelet.getId().equalsIgnoreCase(actionCodelet.getMotorCodeletId())) { - actionCodelet.addOutputs(motorCodelet.getInputs()); - } - } + if (soarCodelet != null && soarCodelet.getId() != null && activityCodelet.getSoarCodeletId() != null) { + if (soarCodelet.getId().equalsIgnoreCase(activityCodelet.getSoarCodeletId())) { + activityCodelet.addBroadcasts(soarCodelet.getOutputs()); } } - /* - * Inputs - */ - if (perceptualCodelets != null) { - for (PerceptualCodelet perceptualCodelet : perceptualCodelets) { - if (perceptualCodelet != null && perceptualCodelet.getId() != null) { - ArrayList perceptualCodeletsIds = actionCodelet.getPerceptualCodeletsIds(); - if (perceptualCodeletsIds != null) { - for (String perceptualCodeletId : perceptualCodeletsIds) { - if (perceptualCodeletId != null && perceptualCodelet.getId().equalsIgnoreCase(perceptualCodeletId)) { - actionCodelet.addInputs(perceptualCodelet.getOutputs()); - } - } - } - } - } - } - if (soarCodelet != null && soarCodelet.getId() != null && actionCodelet.getSoarCodeletId() != null) { - if (soarCodelet.getId().equalsIgnoreCase(actionCodelet.getSoarCodeletId())) { - actionCodelet.addBroadcasts(soarCodelet.getOutputs()); - } - } - actionCodelet.addInput(actionSequencePlanMemoryContainer); + activityCodelet.addInput(actionSequencePlanMemoryContainer); } } } @@ -674,20 +623,6 @@ public void setAppraisalCodelet(AppraisalCodelet appraisalCodelet) { this.appraisalCodelet = appraisalCodelet; } - /** - * @param actionFromPlanningCodelets the actionFromPlanningCodelets to set - */ - public void setActionFromPlanningCodelets(List actionFromPlanningCodelets) { - this.actionFromPlanningCodelets = actionFromPlanningCodelets; - } - - /** - * @param actionFromPerceptionCodelets the actionFromPerceptionCodelets to set - */ - public void setActionFromPerceptionCodelets(List actionFromPerceptionCodelets) { - this.actionFromPerceptionCodelets = actionFromPerceptionCodelets; - } - /** * @param behaviorCodelets the behaviorCodelets to set */ @@ -890,30 +825,30 @@ public List getBehaviorCodelets() { } /** - * @return the actionFromPlanningCodelets + * @return the activityTrackingCodelet */ - public List getActionFromPlanningCodelets() { - return actionFromPlanningCodelets; + public ActivityTrackingCodelet getActivityTrackingCodelet() { + return activityTrackingCodelet; } /** - * @return the actionFromPerceptionCodelets + * @param activityTrackingCodelet the activityTrackingCodelet to set */ - public List getActionFromPerceptionCodelets() { - return actionFromPerceptionCodelets; + public void setActivityTrackingCodelet(ActivityTrackingCodelet activityTrackingCodelet) { + this.activityTrackingCodelet = activityTrackingCodelet; } /** - * @return the activityTrackingCodelet + * @return the activityCodelets */ - public ActivityTrackingCodelet getActivityTrackingCodelet() { - return activityTrackingCodelet; + public List getActivityCodelets() { + return activityCodelets; } /** - * @param activityTrackingCodelet the activityTrackingCodelet to set + * @param activityCodelets the activityCodelets to set */ - public void setActivityTrackingCodelet(ActivityTrackingCodelet activityTrackingCodelet) { - this.activityTrackingCodelet = activityTrackingCodelet; + public void setActivityCodelets(List activityCodelets) { + this.activityCodelets = activityCodelets; } } diff --git a/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java b/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java index 0b41c19..ac93c81 100644 --- a/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java +++ b/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java @@ -12,7 +12,7 @@ ******************************************************************************/ package br.unicamp.meca.models; -import br.unicamp.meca.system1.codelets.ActionFromPlanningCodelet; +import br.unicamp.meca.system1.codelets.ActivityCodelet; /** * This class represents the MECA Action Sequence Plan. This Action Sequence Plan @@ -22,7 +22,7 @@ * them is the current action that should be undertaken in the plan. * * @author A. L. O. Paraense - * @see ActionFromPlanningCodelet + * @see ActivityCodelet * */ public class ActionSequencePlan { diff --git a/src/main/java/br/unicamp/meca/system1/codelets/ActionFromPlanningCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/ActionFromPlanningCodelet.java deleted file mode 100644 index 59b760f..0000000 --- a/src/main/java/br/unicamp/meca/system1/codelets/ActionFromPlanningCodelet.java +++ /dev/null @@ -1,238 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2018 DCA-FEEC-UNICAMP and Ericsson Research * - * All rights reserved. This program and the accompanying materials * - * are made available under the terms of the GNU Lesser Public License v3 * - * which accompanies this distribution, and is available at * - * http://www.gnu.org/licenses/lgpl.html * - * * - * Contributors: * - * R. R. Gudwin, A. L. O. Paraense, E. Froes, W. Gibaut, S. de Paula, * - * E. Castro, V. Figueredo and K. Raizer * - * * - ******************************************************************************/ -package br.unicamp.meca.system1.codelets; - -import java.util.ArrayList; - -import br.unicamp.cst.core.entities.Codelet; -import br.unicamp.cst.core.entities.Memory; -import br.unicamp.cst.core.exceptions.CodeletActivationBoundsException; -import br.unicamp.meca.mind.MecaMind; -import br.unicamp.meca.models.ActionSequencePlan; -import br.unicamp.meca.models.ActionStep; - -/** - * This class represents the MECA Action From Planning Codelet. This Action From Planning - * Codelet allows inputs from one or more of the PerceptualCodelets and the ActionSequencePlan - * with greatest activation. It outputs - * necessarily to a MotorCodelet. As the name suggests, the idea behind this - * action from planning codelet is to provide an action following a specific plan from the behavior generator in System 1. - *

- * Usually, Action From Planning Codelets are application-specific, and the MECA - * software implementation just provides basic template class, which is a - * wrapper to CST's {@link Codelet}, to be reused while building an application - * using MECA. - * - * @author A. L. O. Paraense - * - */ -public abstract class ActionFromPlanningCodelet extends Codelet { - - protected String id; - - protected ArrayList perceptualCodeletsIds; - protected ArrayList perceptualMemories; - - protected String soarCodeletId; - protected Memory broadcastMemory; - - protected Memory actionSequencePlanMemoryContainer; - - protected String motorCodeletId; - protected Memory motorMemory; - - /** - * Creates a MECA Action From Planning Codelet. - * - * @param id - * the id of the Action From Planning Codelet. Must be unique per - * Reactive Behavioral Codelet. - * @param perceptualCodeletsIds - * the list of ids of the Perceptual Codelets whose outputs will - * be read by this Action From Planning Codelet. - * @param motorCodeletId - * the id of the Motor Codelet which will read the outputs of - * this Action From Planning Codelet. - * @param soarCodeletId - * the id of the Soar Codelet whose outputs will be read by this - * Action From Planning Codelet. - */ - public ActionFromPlanningCodelet(String id, ArrayList perceptualCodeletsIds, String motorCodeletId, - String soarCodeletId) { - super(); - setName(id); - this.id = id; - this.motorCodeletId = motorCodeletId; - this.perceptualCodeletsIds = perceptualCodeletsIds; - this.soarCodeletId = soarCodeletId; - } - - @Override - public void accessMemoryObjects() { - - int index=0; - - if(perceptualMemories == null || perceptualMemories.size() == 0) { - - perceptualMemories = new ArrayList<>(); - - if(perceptualCodeletsIds != null) { - - for(String perceptualCodeletId : perceptualCodeletsIds) { - Memory perceptualMemory = this.getInput(perceptualCodeletId, index); - perceptualMemories.add(perceptualMemory); - } - } - } - - if(broadcastMemory == null) { - broadcastMemory = this.getBroadcast(soarCodeletId, index); - } - - if(actionSequencePlanMemoryContainer == null) - actionSequencePlanMemoryContainer = this.getInput(MecaMind.ACTION_SEQUENCE_PLAN_ID, index); - - if(motorMemory==null && motorCodeletId!=null) - motorMemory = this.getOutput(motorCodeletId, index); - - } - - @Override - public void calculateActivation() { - - try { - if(actionSequencePlanMemoryContainer != null && actionSequencePlanMemoryContainer.getI() != null && actionSequencePlanMemoryContainer.getI() instanceof ActionSequencePlan) { - - ActionSequencePlan actionSequencePlan = (ActionSequencePlan) actionSequencePlanMemoryContainer.getI(); - ActionStep currentActionId = actionSequencePlan.getCurrentActionStep(); - - if(currentActionId != null && currentActionId.getActionId().equalsIgnoreCase(id)) { - setActivation(actionSequencePlanMemoryContainer.getEvaluation()); - }else { - setActivation(0.0d); - } - } - - } catch (CodeletActivationBoundsException e) { - e.printStackTrace(); - } - } - - @Override - public void proc() { - - if(actionSequencePlanMemoryContainer != null && actionSequencePlanMemoryContainer.getI() != null && actionSequencePlanMemoryContainer.getI() instanceof ActionSequencePlan) { - - ActionSequencePlan actionSequencePlan = (ActionSequencePlan) actionSequencePlanMemoryContainer.getI(); - String currentActionId = actionSequencePlan.getCurrentActionStep().getActionId(); - - if(currentActionId != null && currentActionId.equalsIgnoreCase(id)) { - proc(perceptualMemories, broadcastMemory, motorMemory); - } - } - } - - /** - * Main method of this Action From Planning Codelet called passing all the input and output memories necessary. - * - * @param perceptualMemories - * the input memories coming from perception. - * @param broadcastMemory - * the input memories coming from the conscious broadcast of the planner. - * @param motorMemory - * the output motor memory to be dispatched to the actuators. - */ - public abstract void proc(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory); - - /** - * Returns the id of the Soar Codelet whose outputs will be read by this - * Action From Planning Codelet. - * - * @return the soarCodeletId - */ - public String getSoarCodeletId() { - return soarCodeletId; - } - - /** - * Sets the id of the Soar Codelet whose outputs will be read by this - * Action From Planning Codelet. - * - * @param soarCodeletId - * the soarCodeletId to set - */ - public void setSoarCodeletId(String soarCodeletId) { - this.soarCodeletId = soarCodeletId; - } - - /** - * Returns the list of the Perceptual Codelet's ids whose outputs will be - * read by this Action From Planning Codelet. - * - * @return the perceptualCodeletsIds - */ - public ArrayList getPerceptualCodeletsIds() { - return perceptualCodeletsIds; - } - - /** - * Sets the list of the Perceptual Codelet's ids whose outputs will be read - * by this Action From Planning Codelet. - * - * @param perceptualCodeletsIds - * the perceptualCodeletsIds to set - */ - public void setPerceptualCodeletsIds(ArrayList perceptualCodeletsIds) { - this.perceptualCodeletsIds = perceptualCodeletsIds; - } - - /** - * Returns the id of this Action From Planning Codelet. - * - * @return the id - */ - public String getId() { - return id; - } - - /** - * Sets the id of this Action From Planning Codelet. - * - * @param id - * the id to set - */ - public void setId(String id) { - this.id = id; - } - - /** - * Returns the id of the Motor Codelet which will read the outputs of this - * Action From Planning Codelet. - * - * @return the motorCodeletId - */ - public String getMotorCodeletId() { - return motorCodeletId; - } - - /** - * Sets the id of the Motor Codelet which will read the outputs of this - * Action From Planning Codelet. - * - * @param motorCodeletId - * the motorCodeletId to set - */ - public void setMotorCodeletId(String motorCodeletId) { - this.motorCodeletId = motorCodeletId; - } -} diff --git a/src/main/java/br/unicamp/meca/system1/codelets/ActionFromPerceptionCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/ActivityCodelet.java similarity index 64% rename from src/main/java/br/unicamp/meca/system1/codelets/ActionFromPerceptionCodelet.java rename to src/main/java/br/unicamp/meca/system1/codelets/ActivityCodelet.java index 5e83631..f5b63fc 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/ActionFromPerceptionCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/ActivityCodelet.java @@ -1,15 +1,6 @@ -/******************************************************************************* - * Copyright (c) 2019 DCA-FEEC-UNICAMP and Ericsson Research * - * All rights reserved. This program and the accompanying materials * - * are made available under the terms of the GNU Lesser Public License v3 * - * which accompanies this distribution, and is available at * - * http://www.gnu.org/licenses/lgpl.html * - * * - * Contributors: * - * R. R. Gudwin, A. L. O. Paraense, E. Froes, W. Gibaut, * - * and K. Raizer. * - * * - ******************************************************************************/ +/** + * + */ package br.unicamp.meca.system1.codelets; import java.util.ArrayList; @@ -17,15 +8,20 @@ import br.unicamp.cst.core.entities.Codelet; import br.unicamp.cst.core.entities.Memory; import br.unicamp.cst.core.exceptions.CodeletActivationBoundsException; +import br.unicamp.meca.mind.MecaMind; +import br.unicamp.meca.models.ActionSequencePlan; +import br.unicamp.meca.models.ActionStep; /** - * This class represents the MECA Action From Perception Codelet. This Action From Perception - * Codelet allows inputs from one or more of the PerceptualCodelets and - * inputs from one or more of the MotivationalCodelets. It outputs + * This class represents the MECA Activity Codelet. This Activity + * Codelet allows inputs from one or more of the PerceptualCodelets, + * inputs from one or more of the MotivationalCodelets and the ActionSequencePlan + * with greatest activation. It outputs * necessarily to a MotorCodelet. As the name suggests, the idea behind this - * action from perception codelet is to provide an action as a purely reaction to the environment in System 1. + * activity codelet is to provide an action as a purely reaction to the environment + * or else based on a plan in System 1. *

- * Usually, Action From Perception Codelets are application-specific, and the MECA + * Usually, Activity Codelets are application-specific, and the MECA * software implementation just provides basic template class, which is a * wrapper to CST's {@link Codelet}, to be reused while building an application * using MECA. @@ -33,8 +29,8 @@ * @author A. L. O. Paraense * */ -public abstract class ActionFromPerceptionCodelet extends Codelet { - +public abstract class ActivityCodelet extends Codelet { + protected String id; protected ArrayList perceptualCodeletsIds; @@ -46,32 +42,37 @@ public abstract class ActionFromPerceptionCodelet extends Codelet { protected String soarCodeletId; protected Memory broadcastMemory; + protected Memory actionSequencePlanMemoryContainer; + protected String motorCodeletId; protected Memory motorMemory; - + /** * - * Creates a MECA Action From Perception Codelet. + * Creates a MECA Activity Codelet. * * @param id - * the id of the Action From Perception Codelet. Must be unique per - * Action From Perception Codelet. + * the id of the Activity Codelet. Must be unique per + * Activity Codelet. * @param perceptualCodeletsIds * the list of ids of the Perceptual Codelets whose outputs will - * be read by this Action From Perception Codelet. + * be read by this Activity Codelet. * @param motivationalCodeletsIds * the list of ids of the Motivational Codelets whose outputs will - * be read by this Action From Perception Codelet. + * be read by this Activity Codelet. * @param motorCodeletId * the id of the Motor Codelet which will read the outputs of - * this Action From Perception Codelet. + * this Activity Codelet. * @param soarCodeletId * the id of the Soar Codelet whose outputs will be read by this - * Action From Perception Codelet. + * Activity Codelet. */ - public ActionFromPerceptionCodelet(String id, ArrayList perceptualCodeletsIds, ArrayList motivationalCodeletsIds, String motorCodeletId, + public ActivityCodelet( + String id, + ArrayList perceptualCodeletsIds, + ArrayList motivationalCodeletsIds, + String motorCodeletId, String soarCodeletId) { - super(); setName(id); this.id = id; this.motorCodeletId = motorCodeletId; @@ -79,10 +80,9 @@ public ActionFromPerceptionCodelet(String id, ArrayList perceptualCodele this.soarCodeletId = soarCodeletId; this.motivationalCodeletsIds = motivationalCodeletsIds; } - + @Override public void accessMemoryObjects() { - int index=0; if(perceptualMemories == null || perceptualMemories.size() == 0) { @@ -119,14 +119,26 @@ public void accessMemoryObjects() { if(motorMemory==null && motorCodeletId!=null) motorMemory = this.getOutput(motorCodeletId, index); + + if(actionSequencePlanMemoryContainer == null) + actionSequencePlanMemoryContainer = this.getInput(MecaMind.ACTION_SEQUENCE_PLAN_ID, index); } - + @Override public void calculateActivation() { - double activation = 0; - if (driveMemories!=null && driveMemories.size() > 0){ + if(actionSequencePlanMemoryContainer != null && actionSequencePlanMemoryContainer.getI() != null && actionSequencePlanMemoryContainer.getI() instanceof ActionSequencePlan) { + + ActionSequencePlan actionSequencePlan = (ActionSequencePlan) actionSequencePlanMemoryContainer.getI(); + ActionStep currentActionId = actionSequencePlan.getCurrentActionStep(); + + if(currentActionId != null && currentActionId.getActionId().equalsIgnoreCase(id)) { + activation = actionSequencePlanMemoryContainer.getEvaluation(); + }else { + activation = 0.0d; + } + }else if (driveMemories!=null && driveMemories.size() > 0){ for (Memory driveMO: driveMemories) { activation += driveMO.getEvaluation(); @@ -153,13 +165,21 @@ public void calculateActivation() { } @Override - public void proc() { - - proc(perceptualMemories, broadcastMemory, motorMemory); + public void proc() { + if(actionSequencePlanMemoryContainer != null && actionSequencePlanMemoryContainer.getI() != null && actionSequencePlanMemoryContainer.getI() instanceof ActionSequencePlan) { + ActionSequencePlan actionSequencePlan = (ActionSequencePlan) actionSequencePlanMemoryContainer.getI(); + String currentActionId = actionSequencePlan.getCurrentActionStep().getActionId(); + + if(currentActionId != null && currentActionId.equalsIgnoreCase(id)) { + proc(perceptualMemories, broadcastMemory, motorMemory); + } + }else { + proc(perceptualMemories, broadcastMemory, motorMemory); + } } /** - * Main method of the Action From Perception Codelet called passing all input and output necessary memories. + * Main method of the Activity Codelet called passing all input and output necessary memories. * * @param perceptualMemories * the input memories coming from perception. @@ -169,10 +189,10 @@ public void proc() { * the output motor memory. */ public abstract void proc(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory); - + /** * Returns the id of the Soar Codelet whose outputs will be read by this - * Action From Perception Codelet. + * Activity Codelet. * * @return the soarCodeletId */ @@ -182,7 +202,7 @@ public String getSoarCodeletId() { /** * Sets the id of the Soar Codelet whose outputs will be read by this - * Action From Perception Codelet. + * Activity Codelet. * * @param soarCodeletId * the soarCodeletId to set @@ -193,7 +213,7 @@ public void setSoarCodeletId(String soarCodeletId) { /** * Returns the list of the Perceptual Codelet's ids whose outputs will be - * read by this Action From Perception Codelet. + * read by this Activity Codelet. * * @return the perceptualCodeletsIds */ @@ -203,7 +223,7 @@ public ArrayList getPerceptualCodeletsIds() { /** * Sets the list of the Perceptual Codelet's ids whose outputs will be read - * by this Action From Perception Codelet. + * by this Activity Codelet. * * @param perceptualCodeletsIds * the perceptualCodeletsIds to set @@ -213,7 +233,7 @@ public void setPerceptualCodeletsIds(ArrayList perceptualCodeletsIds) { } /** - * Returns the id of this Action From Perception Codelet. + * Returns the id of this Activity Codelet. * * @return the id */ @@ -222,7 +242,7 @@ public String getId() { } /** - * Sets the id of this Action From Perception Codelet. + * Sets the id of this Activity Codelet. * * @param id * the id to set @@ -233,7 +253,7 @@ public void setId(String id) { /** * Returns the id of the Motor Codelet which will read the outputs of this - * Action From Perception Codelet. + * Activity Codelet. * * @return the motorCodeletId */ @@ -243,7 +263,7 @@ public String getMotorCodeletId() { /** * Sets the id of the Motor Codelet which will read the outputs of this - * Action From Perception Codelet. + * Activity Codelet. * * @param motorCodeletId * the motorCodeletId to set diff --git a/src/test/java/br/unicamp/meca/mind/MecaMindTest.java b/src/test/java/br/unicamp/meca/mind/MecaMindTest.java index 825c590..906cc4f 100644 --- a/src/test/java/br/unicamp/meca/mind/MecaMindTest.java +++ b/src/test/java/br/unicamp/meca/mind/MecaMindTest.java @@ -18,9 +18,9 @@ import br.unicamp.cst.core.entities.MemoryContainer; import br.unicamp.cst.core.exceptions.CodeletActivationBoundsException; import br.unicamp.cst.util.MindViewer; -import br.unicamp.meca.mind.action.Test1ActionFromPerceptionCodelet; -import br.unicamp.meca.mind.action.Test1ActionFromPlanningCodelet; -import br.unicamp.meca.mind.action.Test2ActionFromPlanningCodelets; +import br.unicamp.meca.mind.action.Test1ActivityCodelet; +import br.unicamp.meca.mind.action.Test2ActivityCodelet; +import br.unicamp.meca.mind.action.Test3ActivityCodelet; import br.unicamp.meca.mind.behavior.Test1AndTest2BehaviorCodelet; import br.unicamp.meca.mind.motivational.TestMotivationalFromPerceptionCodelet; import br.unicamp.meca.mind.motivational.TestMotivationalFromPlanningCodelet; @@ -29,9 +29,7 @@ import br.unicamp.meca.mind.sensory.TestPerceptionSensoryCodelet; import br.unicamp.meca.mind.sensory.TestPlanningSensoryCodelet; import br.unicamp.meca.models.ActionSequencePlan; -import br.unicamp.meca.models.ActionStep; -import br.unicamp.meca.system1.codelets.ActionFromPerceptionCodelet; -import br.unicamp.meca.system1.codelets.ActionFromPlanningCodelet; +import br.unicamp.meca.system1.codelets.ActivityCodelet; import br.unicamp.meca.system1.codelets.ActivityTrackingCodelet; import br.unicamp.meca.system1.codelets.BehaviorCodelet; import br.unicamp.meca.system1.codelets.IMotorCodelet; @@ -54,6 +52,14 @@ public class MecaMindTest { private static TestPlanningSensoryCodelet testPlanningSensoryCodelet; private static TestMotorCodelet testMotorCodelet; + + private static List perceptualCodelets; + + private static List sensoryCodelets; + + private static List motivationalCodelets; + + private static List activityCodelets; @BeforeClass public static void setup() throws InterruptedException { @@ -61,21 +67,18 @@ public static void setup() throws InterruptedException { mecaMind = new MecaMind("MecaMind"); /* Sensory codelets we are about to create for this Meca mind*/ - List sensoryCodelets = new ArrayList<>(); + sensoryCodelets = new ArrayList<>(); /* Lists that will hold the codelets ids. This is important * for the MECA mind mounting algorithm be able to glue the * codelets according to the reference architecture * */ - ArrayList sensoryCodeletsIds = new ArrayList<>(); - + ArrayList sensoryPerceptionCodeletsIds = new ArrayList<>(); + testPerceptionSensoryCodelet = new TestPerceptionSensoryCodelet("TestPerceptionSensoryCodelet"); sensoryCodelets.add(testPerceptionSensoryCodelet); - sensoryCodeletsIds.add(testPerceptionSensoryCodelet.getId()); + sensoryPerceptionCodeletsIds.add(testPerceptionSensoryCodelet.getId()); - testPlanningSensoryCodelet = new TestPlanningSensoryCodelet("TestPlanningSensoryCodelet"); - sensoryCodelets.add(testPlanningSensoryCodelet); - sensoryCodeletsIds.add(testPlanningSensoryCodelet.getId()); /* * Now it is a good time to create the motor codelets, before the Behavioral ones, @@ -93,26 +96,27 @@ public static void setup() throws InterruptedException { * This codelet must receive the ids of the sensory codelets, * in order to be glued to them, receiving their inputs. */ - List perceptualCodelets = new ArrayList<>(); - ArrayList perceptualCodeletsIds = new ArrayList<>(); + perceptualCodelets = new ArrayList<>(); + ArrayList perceptualPerceptionCodeletsIds = new ArrayList<>(); - TestPerceptualCodelet testPerceptualCodelet = new TestPerceptualCodelet("TestPerceptualCodelet", sensoryCodeletsIds); - perceptualCodeletsIds.add(testPerceptualCodelet.getId()); + TestPerceptualCodelet testPerceptualCodelet = new TestPerceptualCodelet("TestPerceptualCodelet", sensoryPerceptionCodeletsIds); + perceptualPerceptionCodeletsIds.add(testPerceptualCodelet.getId()); perceptualCodelets.add(testPerceptualCodelet); + /* * Next step is to create the motivational codelets. * This codelets must receive the ids of the sensory codelets, * in order to be glued to them, receiving their inputs. */ - List motivationalCodelets = new ArrayList<>(); + motivationalCodelets = new ArrayList<>(); ArrayList testMotivationalFromPerceptionCodeletIds = new ArrayList<>(); TestMotivationalFromPerceptionCodelet testMotivationalFromPerceptionCodelet; try { - testMotivationalFromPerceptionCodelet = new TestMotivationalFromPerceptionCodelet("TestMotivationalFromPerceptionCodelet", 0, 0.45, 0.9, sensoryCodeletsIds, new HashMap()); + testMotivationalFromPerceptionCodelet = new TestMotivationalFromPerceptionCodelet("TestMotivationalFromPerceptionCodelet", 0, 0.45, 0.9, sensoryPerceptionCodeletsIds, new HashMap()); testMotivationalFromPerceptionCodeletIds.add(testMotivationalFromPerceptionCodelet.getId()); motivationalCodelets.add(testMotivationalFromPerceptionCodelet); @@ -120,60 +124,18 @@ public static void setup() throws InterruptedException { e.printStackTrace(); } - ArrayList testMotivationalFromPlanningCodeletIds = new ArrayList<>(); - - TestMotivationalFromPlanningCodelet testMotivationalFromPlanningCodelet; - - try { - - testMotivationalFromPlanningCodelet = new TestMotivationalFromPlanningCodelet("TestMotivationalFromPlanningCodelet", 0, 0.5, 0.9, sensoryCodeletsIds, new HashMap()); - testMotivationalFromPlanningCodeletIds.add(testMotivationalFromPlanningCodelet.getId()); - motivationalCodelets.add(testMotivationalFromPlanningCodelet); - } catch (CodeletActivationBoundsException e) { - e.printStackTrace(); - } - /* * Last step is to create the behavioral codelets, * They receive the ids of the perceptual codelets and * motor codelets, in order to be glued to them, according * to the reference architecture. */ - - List actionFromPerceptionCodelets = new ArrayList<>(); - - Test1ActionFromPerceptionCodelet test1ActionFromPerceptionCodelet = new Test1ActionFromPerceptionCodelet("Test1ActionFromPerceptionCodelet", perceptualCodeletsIds, testMotivationalFromPerceptionCodeletIds, testMotorCodelet.getId(), null); - actionFromPerceptionCodelets.add(test1ActionFromPerceptionCodelet); - - List actionFromPlanningCodelets = new ArrayList<>(); - - Test1ActionFromPlanningCodelet test1ActionFromPlanningCodelet = new Test1ActionFromPlanningCodelet("Test1ActionFromPlanningCodelet", perceptualCodeletsIds, testMotorCodelet.getId(), null); - actionFromPlanningCodelets.add(test1ActionFromPlanningCodelet); - - Test2ActionFromPlanningCodelets test2ActionFromPlanningCodelets = new Test2ActionFromPlanningCodelets("Test2ActionFromPlanningCodelets", perceptualCodeletsIds, testMotorCodelet.getId(), null); - actionFromPlanningCodelets.add(test2ActionFromPlanningCodelets); - ActivityTrackingCodelet activityTrackingCodelet = new ActivityTrackingCodelet("ActivityTrackingCodelet", perceptualCodeletsIds) { - - @Override - public void trackActionSequencePlan(ArrayList perceptualMemories, ActionSequencePlan actionSequencePlan) { - - if(actionSequencePlan == null || actionSequencePlan.getActionStepSequence() == null) { - return; - } - - actionSequencePlan.setCurrentActionIdIndex(0); - - //In this test, will never go on to the second action. We could have limit on perceptual memory to move on, though. - } - }; + activityCodelets = new ArrayList<>(); - List behaviorCodelets = new ArrayList<>(); - - Test1AndTest2BehaviorCodelet test1AndTest2BehaviorCodelet = new Test1AndTest2BehaviorCodelet("Test1AndTest2BehaviorCodelet", perceptualCodeletsIds, testMotivationalFromPlanningCodeletIds, null); - behaviorCodelets.add(test1AndTest2BehaviorCodelet); - - + Test1ActivityCodelet test1ActivityCodelet = new Test1ActivityCodelet("Test1Activity", perceptualPerceptionCodeletsIds, testMotivationalFromPerceptionCodeletIds, testMotorCodelet.getId(), null); + activityCodelets.add(test1ActivityCodelet); + /* * Inserting the System 1 codelets inside MECA mind @@ -182,11 +144,21 @@ public void trackActionSequencePlan(ArrayList perceptualMemories, Action mecaMind.setIMotorCodelets(motorCodelets); mecaMind.setPerceptualCodelets(perceptualCodelets); mecaMind.setMotivationalCodelets(motivationalCodelets); - mecaMind.setActionFromPerceptionCodelets(actionFromPerceptionCodelets); - mecaMind.setActionFromPlanningCodelets(actionFromPlanningCodelets); - mecaMind.setBehaviorCodelets(behaviorCodelets); - mecaMind.setActivityTrackingCodelet(activityTrackingCodelet); + mecaMind.setActivityCodelets(activityCodelets); + + + } + + @AfterClass + public static void tearDown() { + + mv.setVisible(false); + mecaMind.shutDown(); + } + @Test + public void testMecaMindMountActivityReactWin() throws InterruptedException { + /* * After passing references to the codelets, we call the method 'MecaMind.mountMecaMind()', which * is responsible for wiring the MecaMind altogether according to the reference architecture, including @@ -209,40 +181,24 @@ public void trackActionSequencePlan(ArrayList perceptualMemories, Action * codelets, which activation has a pivotal role. */ List listOfCodelets = new ArrayList<>(); - listOfCodelets.addAll(mecaMind.getActionFromPerceptionCodelets()); - listOfCodelets.addAll(mecaMind.getActionFromPlanningCodelets()); - listOfCodelets.addAll(mecaMind.getBehaviorCodelets()); + listOfCodelets.addAll(mecaMind.getActivityCodelets()); mv = new MindViewer(mecaMind, "MECA Mind Inspection - "+mecaMind.getId(), listOfCodelets); mv.setVisible(true); Thread.sleep(1000); - } - - @AfterClass - public static void tearDown() { - - mv.setVisible(false); - mecaMind.shutDown(); - } - - @Test - public void testMecaMindMountActionFromPerceptionWin() throws InterruptedException { - //do something String contentInTheEnvironment = "Something"; testPerceptionSensoryCodelet.setSensoryContents(contentInTheEnvironment); - testPlanningSensoryCodelet.setSensoryContents(null); - Thread.sleep(1000); //test something - String messageExpected = "Test1ActionFromPerception - A black dog"; + String messageExpected = "Test1Activity - A black dog"; MemoryContainer motorMemory = (MemoryContainer) testMotorCodelet.getInput("TestMotorCodelet"); @@ -254,8 +210,92 @@ public void testMecaMindMountActionFromPerceptionWin() throws InterruptedExcepti } @Test - public void testMecaMindMountActionFromPlanningWin() throws InterruptedException { + public void testMecaMindMountActivityFromPlanningWin() throws InterruptedException { + + ArrayList sensoryPlanningCodeletsIds = new ArrayList<>(); + testPlanningSensoryCodelet = new TestPlanningSensoryCodelet("TestPlanningSensoryCodelet"); + sensoryCodelets.add(testPlanningSensoryCodelet); + sensoryPlanningCodeletsIds.add(testPlanningSensoryCodelet.getId()); + + ArrayList perceptualPlanningCodeletsIds = new ArrayList<>(); + TestPerceptualCodelet testPlanningCodelet = new TestPerceptualCodelet("TestPlanningCodelet", sensoryPlanningCodeletsIds); + perceptualPlanningCodeletsIds.add(testPlanningCodelet.getId()); + perceptualCodelets.add(testPlanningCodelet); + + ArrayList testMotivationalFromPlanningCodeletIds = new ArrayList<>(); + + TestMotivationalFromPlanningCodelet testMotivationalFromPlanningCodelet; + + try { + + testMotivationalFromPlanningCodelet = new TestMotivationalFromPlanningCodelet("TestMotivationalFromPlanningCodelet", 0, 0.5, 0.9, sensoryPlanningCodeletsIds, new HashMap()); + testMotivationalFromPlanningCodeletIds.add(testMotivationalFromPlanningCodelet.getId()); + motivationalCodelets.add(testMotivationalFromPlanningCodelet); + } catch (CodeletActivationBoundsException e) { + e.printStackTrace(); + } + + Test2ActivityCodelet test2ActivityCodelet = new Test2ActivityCodelet("Test2Activity", perceptualPlanningCodeletsIds, testMotivationalFromPlanningCodeletIds, testMotorCodelet.getId(), null); + activityCodelets.add(test2ActivityCodelet); + + Test3ActivityCodelet test3ActivityCodelets = new Test3ActivityCodelet("Test3Activity", perceptualPlanningCodeletsIds, testMotivationalFromPlanningCodeletIds, testMotorCodelet.getId(), null); + activityCodelets.add(test3ActivityCodelets); + + ActivityTrackingCodelet activityTrackingCodelet = new ActivityTrackingCodelet("ActivityTrackingCodelet", perceptualPlanningCodeletsIds) { + + @Override + public void trackActionSequencePlan(ArrayList perceptualMemories, ActionSequencePlan actionSequencePlan) { + + if(actionSequencePlan == null || actionSequencePlan.getActionStepSequence() == null) { + return; + } + + actionSequencePlan.setCurrentActionIdIndex(0); + + //In this test, will never go on to the second action. We could have limit on perceptual memory to move on, though. + } + }; + + + List behaviorCodelets = new ArrayList<>(); + + Test1AndTest2BehaviorCodelet test1AndTest2BehaviorCodelet = new Test1AndTest2BehaviorCodelet("Test1AndTest2BehaviorCodelet", perceptualPlanningCodeletsIds, testMotivationalFromPlanningCodeletIds, null); + behaviorCodelets.add(test1AndTest2BehaviorCodelet); + mecaMind.setBehaviorCodelets(behaviorCodelets); + mecaMind.setActivityTrackingCodelet(activityTrackingCodelet); + + /* + * After passing references to the codelets, we call the method 'MecaMind.mountMecaMind()', which + * is responsible for wiring the MecaMind altogether according to the reference architecture, including + * the creation of memory objects and containers which glue them together. This method is of pivotal + * importance and inside it resides all the value from the reference architecture created - the idea is + * that the user only has to create the codelets, put them inside lists of differente types and call + * this method, which transparently glue the codelets together accordingly to the MECA reference + * architecture. + */ + mecaMind.mountMecaMind(); + + /* + * Starting the mind + */ + mecaMind.start(); + + /* + * Instead of inserting the sensory codelets in the + * CST visualization tool, let's insert the behaviroal + * codelets, which activation has a pivotal role. + */ + List listOfCodelets = new ArrayList<>(); + listOfCodelets.addAll(mecaMind.getActivityCodelets()); + listOfCodelets.addAll(mecaMind.getBehaviorCodelets()); + + mv = new MindViewer(mecaMind, "MECA Mind Inspection - "+mecaMind.getId(), listOfCodelets); + mv.setVisible(true); + + Thread.sleep(1000); + + //do something String contentInTheEnvironment = "Something"; @@ -268,7 +308,7 @@ public void testMecaMindMountActionFromPlanningWin() throws InterruptedException //test something - String messageExpected = "Test1ActionFromPlanning - A black dog"; + String messageExpected = "Test2Activity - A black dog"; MemoryContainer motorMemory = (MemoryContainer) testMotorCodelet.getInput("TestMotorCodelet"); diff --git a/src/test/java/br/unicamp/meca/mind/action/Test1ActionFromPlanningCodelet.java b/src/test/java/br/unicamp/meca/mind/action/Test1ActionFromPlanningCodelet.java deleted file mode 100644 index 1ed9c58..0000000 --- a/src/test/java/br/unicamp/meca/mind/action/Test1ActionFromPlanningCodelet.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * - */ -package br.unicamp.meca.mind.action; - -import java.util.ArrayList; - -import br.unicamp.cst.core.entities.Memory; -import br.unicamp.cst.core.entities.MemoryContainer; -import br.unicamp.meca.system1.codelets.ActionFromPlanningCodelet; - -/** - * @author andre - * - */ -public class Test1ActionFromPlanningCodelet extends ActionFromPlanningCodelet { - - public Test1ActionFromPlanningCodelet(String id, ArrayList perceptualCodeletsIds, String motorCodeletId, - String soarCodeletId) { - super(id, perceptualCodeletsIds, motorCodeletId, soarCodeletId); - } - - @Override - public void proc(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory) { - if(perceptualMemories == null || perceptualMemories.size() == 0) { - return; - } - - motorMemory.setI(null); - - for(Memory memory: perceptualMemories) { - if(memory.getI()!=null && memory.getI() instanceof String) { - String perceptualContent = (String) memory.getI(); - - ((MemoryContainer) motorMemory).setI("Test1ActionFromPlanning - "+perceptualContent,getActivation(),id); - } - } - } -} diff --git a/src/test/java/br/unicamp/meca/mind/action/Test1ActionFromPerceptionCodelet.java b/src/test/java/br/unicamp/meca/mind/action/Test1ActivityCodelet.java similarity index 64% rename from src/test/java/br/unicamp/meca/mind/action/Test1ActionFromPerceptionCodelet.java rename to src/test/java/br/unicamp/meca/mind/action/Test1ActivityCodelet.java index 6262a3a..f61e0a2 100644 --- a/src/test/java/br/unicamp/meca/mind/action/Test1ActionFromPerceptionCodelet.java +++ b/src/test/java/br/unicamp/meca/mind/action/Test1ActivityCodelet.java @@ -7,22 +7,28 @@ import br.unicamp.cst.core.entities.Memory; import br.unicamp.cst.core.entities.MemoryContainer; -import br.unicamp.meca.system1.codelets.ActionFromPerceptionCodelet; +import br.unicamp.meca.system1.codelets.ActivityCodelet; /** * @author andre * */ -public class Test1ActionFromPerceptionCodelet extends ActionFromPerceptionCodelet { +public class Test1ActivityCodelet extends ActivityCodelet { - public Test1ActionFromPerceptionCodelet(String id, ArrayList perceptualCodeletsIds, + /** + * @param id + * @param perceptualCodeletsIds + * @param motivationalCodeletsIds + * @param motorCodeletId + * @param soarCodeletId + */ + public Test1ActivityCodelet(String id, ArrayList perceptualCodeletsIds, ArrayList motivationalCodeletsIds, String motorCodeletId, String soarCodeletId) { super(id, perceptualCodeletsIds, motivationalCodeletsIds, motorCodeletId, soarCodeletId); } @Override public void proc(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory) { - if(perceptualMemories == null || perceptualMemories.size() == 0) { return; } @@ -33,9 +39,8 @@ public void proc(ArrayList perceptualMemories, Memory broadcastMemory, M if(memory.getI()!=null && memory.getI() instanceof String) { String perceptualContent = (String) memory.getI(); - ((MemoryContainer) motorMemory).setI("Test1ActionFromPerception - "+perceptualContent,getActivation(),id); + ((MemoryContainer) motorMemory).setI("Test1Activity - "+perceptualContent,getActivation(),id); } } } - } diff --git a/src/test/java/br/unicamp/meca/mind/action/Test2ActionFromPlanningCodelets.java b/src/test/java/br/unicamp/meca/mind/action/Test2ActionFromPlanningCodelets.java deleted file mode 100644 index ece7ea5..0000000 --- a/src/test/java/br/unicamp/meca/mind/action/Test2ActionFromPlanningCodelets.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * - */ -package br.unicamp.meca.mind.action; - -import java.util.ArrayList; - -import br.unicamp.cst.core.entities.Memory; -import br.unicamp.cst.core.entities.MemoryContainer; -import br.unicamp.meca.system1.codelets.ActionFromPlanningCodelet; - -/** - * @author andre - * - */ -public class Test2ActionFromPlanningCodelets extends ActionFromPlanningCodelet { - - public Test2ActionFromPlanningCodelets(String id, ArrayList perceptualCodeletsIds, String motorCodeletId, - String soarCodeletId) { - super(id, perceptualCodeletsIds, motorCodeletId, soarCodeletId); - } - - @Override - public void proc(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory) { - if(perceptualMemories == null || perceptualMemories.size() == 0) { - return; - } - - motorMemory.setI(null); - - for(Memory memory: perceptualMemories) { - if(memory.getI()!=null && memory.getI() instanceof String) { - String perceptualContent = (String) memory.getI(); - - ((MemoryContainer) motorMemory).setI("Test2ActionFromPlanning - "+perceptualContent,getActivation(),id); - } - } - - } - -} diff --git a/src/test/java/br/unicamp/meca/mind/action/Test2ActivityCodelet.java b/src/test/java/br/unicamp/meca/mind/action/Test2ActivityCodelet.java new file mode 100644 index 0000000..9d78e85 --- /dev/null +++ b/src/test/java/br/unicamp/meca/mind/action/Test2ActivityCodelet.java @@ -0,0 +1,46 @@ +/** + * + */ +package br.unicamp.meca.mind.action; + +import java.util.ArrayList; + +import br.unicamp.cst.core.entities.Memory; +import br.unicamp.cst.core.entities.MemoryContainer; +import br.unicamp.meca.system1.codelets.ActivityCodelet; + +/** + * @author andre + * + */ +public class Test2ActivityCodelet extends ActivityCodelet { + + /** + * @param id + * @param perceptualCodeletsIds + * @param motivationalCodeletsIds + * @param motorCodeletId + * @param soarCodeletId + */ + public Test2ActivityCodelet(String id, ArrayList perceptualCodeletsIds, + ArrayList motivationalCodeletsIds, String motorCodeletId, String soarCodeletId) { + super(id, perceptualCodeletsIds, motivationalCodeletsIds, motorCodeletId, soarCodeletId); + } + + @Override + public void proc(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory) { + if(perceptualMemories == null || perceptualMemories.size() == 0) { + return; + } + + motorMemory.setI(null); + + for(Memory memory: perceptualMemories) { + if(memory.getI()!=null && memory.getI() instanceof String) { + String perceptualContent = (String) memory.getI(); + + ((MemoryContainer) motorMemory).setI("Test2Activity - "+perceptualContent,getActivation(),id); + } + } + } +} diff --git a/src/test/java/br/unicamp/meca/mind/action/Test3ActivityCodelet.java b/src/test/java/br/unicamp/meca/mind/action/Test3ActivityCodelet.java new file mode 100644 index 0000000..66d7524 --- /dev/null +++ b/src/test/java/br/unicamp/meca/mind/action/Test3ActivityCodelet.java @@ -0,0 +1,46 @@ +/** + * + */ +package br.unicamp.meca.mind.action; + +import java.util.ArrayList; + +import br.unicamp.cst.core.entities.Memory; +import br.unicamp.cst.core.entities.MemoryContainer; +import br.unicamp.meca.system1.codelets.ActivityCodelet; + +/** + * @author andre + * + */ +public class Test3ActivityCodelet extends ActivityCodelet { + + /** + * @param id + * @param perceptualCodeletsIds + * @param motivationalCodeletsIds + * @param motorCodeletId + * @param soarCodeletId + */ + public Test3ActivityCodelet(String id, ArrayList perceptualCodeletsIds, + ArrayList motivationalCodeletsIds, String motorCodeletId, String soarCodeletId) { + super(id, perceptualCodeletsIds, motivationalCodeletsIds, motorCodeletId, soarCodeletId); + } + + @Override + public void proc(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory) { + if(perceptualMemories == null || perceptualMemories.size() == 0) { + return; + } + + motorMemory.setI(null); + + for(Memory memory: perceptualMemories) { + if(memory.getI()!=null && memory.getI() instanceof String) { + String perceptualContent = (String) memory.getI(); + + ((MemoryContainer) motorMemory).setI("Test3Activity - "+perceptualContent,getActivation(),id); + } + } + } +} diff --git a/src/test/java/br/unicamp/meca/mind/behavior/Test1AndTest2BehaviorCodelet.java b/src/test/java/br/unicamp/meca/mind/behavior/Test1AndTest2BehaviorCodelet.java index 18e58ae..13b88a0 100644 --- a/src/test/java/br/unicamp/meca/mind/behavior/Test1AndTest2BehaviorCodelet.java +++ b/src/test/java/br/unicamp/meca/mind/behavior/Test1AndTest2BehaviorCodelet.java @@ -16,6 +16,8 @@ * */ public class Test1AndTest2BehaviorCodelet extends BehaviorCodelet { + + private ActionSequencePlan actionSequencePlan; public Test1AndTest2BehaviorCodelet(String id, ArrayList perceptualCodeletsIds, ArrayList motivationalCodeletsIds, String soarCodeletId) { @@ -25,11 +27,13 @@ public Test1AndTest2BehaviorCodelet(String id, ArrayList perceptualCodel @Override protected ActionSequencePlan buildActionSequencePlan(ArrayList perceptualMemories) { - ActionStep as1 = new ActionStepTest("Test1ActionFromPlanningCodelet"); - ActionStep as2 = new ActionStepTest("Test2ActionFromPlanningCodelet"); - ActionSequencePlan test1Test2ActionSequence = new ActionSequencePlan(new ActionStep[] {as1,as2}); - - return test1Test2ActionSequence; + if(actionSequencePlan == null) { + ActionStep as1 = new ActionStepTest("Test2Activity"); + ActionStep as2 = new ActionStepTest("Test3Activity"); + actionSequencePlan = new ActionSequencePlan(new ActionStep[] {as1,as2}); + } + + return actionSequencePlan; } } diff --git a/src/test/java/br/unicamp/meca/models/ActionStepTest.java b/src/test/java/br/unicamp/meca/models/ActionStepTest.java index f4041a6..a01e785 100644 --- a/src/test/java/br/unicamp/meca/models/ActionStepTest.java +++ b/src/test/java/br/unicamp/meca/models/ActionStepTest.java @@ -29,7 +29,7 @@ public void setUp() { @Override public boolean stopCondition(List perceptions) { - return(true); + return(false); } @Test From 3e2bb2ba6a90f04b8f54b3ebed5d5eef19d149b2 Mon Sep 17 00:00:00 2001 From: Ricardo Gudwin Date: Fri, 11 Sep 2020 14:21:44 -0300 Subject: [PATCH 20/89] Integration of Memory Groups Upgrade to Gradle 6.5 --- build.gradle | 4 ++-- gradle/wrapper/gradle-wrapper.properties | 2 +- .../java/br/unicamp/meca/mind/MecaMind.java | 18 ++++++++++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 672f931..13f175b 100644 --- a/build.gradle +++ b/build.gradle @@ -30,8 +30,8 @@ repositories { } dependencies { - api 'com.github.CST-Group:cst:5e79d5e4271d82193dda0e2826fef43d13b9f100' - // api ':cst:0.5.1-full' + //api 'com.github.CST-Group:cst:5e79d5e4271d82193dda0e2826fef43d13b9f100' + api ':cst:0.5.1-full' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' testImplementation 'org.ros.rosjava_messages:rosjava_test_msgs:0.3.0' diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 44e7c4d..622ab64 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/br/unicamp/meca/mind/MecaMind.java b/src/main/java/br/unicamp/meca/mind/MecaMind.java index 53b2702..a84f81e 100644 --- a/src/main/java/br/unicamp/meca/mind/MecaMind.java +++ b/src/main/java/br/unicamp/meca/mind/MecaMind.java @@ -42,6 +42,7 @@ import br.unicamp.meca.system2.codelets.ExpectationCodelet; import br.unicamp.meca.system2.codelets.GoalCodelet; import br.unicamp.meca.system2.codelets.SoarCodelet; +import java.util.Iterator; /** * This class represents the MECA's agent mind.This is the main class to be used @@ -49,6 +50,7 @@ * * @author A. L. O. Paraense * @author E. Froes + * @author R. R. Gudwin * @see Mind */ public class MecaMind extends Mind { @@ -72,6 +74,7 @@ public class MecaMind extends Mind { private Memory actionSequencePlanMemoryContainer; private Memory actionSequencePlanRequestMemoryContainer; private ActivityTrackingCodelet activityTrackingCodelet; + private static HashMap memoryGroups = new HashMap(); /* * System 2 @@ -154,12 +157,23 @@ public void mountMecaMind() { mountActivityTrackingCodelet(); mountActivityCodelets(); mountModules(); + mountMemoryGroups(); } private void mountActionSequencePlanMemory() { actionSequencePlanMemoryContainer = createMemoryContainer(ACTION_SEQUENCE_PLAN_ID); actionSequencePlanRequestMemoryContainer = createMemoryContainer(ACTION_SEQUENCE_PLAN_REQUEST_ID); } + + + private void mountMemoryGroups() { + Iterator it = memoryGroups.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry pair = (Map.Entry)it.next(); + registerMemory((String)pair.getKey(),(String)pair.getValue() ); + it.remove(); // avoids a ConcurrentModificationException + } + } private void mountModules() { if (getSoarCodelet() != null) { @@ -844,6 +858,10 @@ public void setActivityTrackingCodelet(ActivityTrackingCodelet activityTrackingC public List getActivityCodelets() { return activityCodelets; } + + public void pregisterMemory(String memoryName, String memoryGroup) { + memoryGroups.put(memoryName, memoryGroup); + } /** * @param activityCodelets the activityCodelets to set From b0e92567f9d158d952d4ce19f535e2909177d01c Mon Sep 17 00:00:00 2001 From: Ricardo Gudwin Date: Mon, 28 Sep 2020 12:58:07 -0300 Subject: [PATCH 21/89] changes in the build.gradle --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 13f175b..0d6e1c3 100644 --- a/build.gradle +++ b/build.gradle @@ -30,8 +30,8 @@ repositories { } dependencies { - //api 'com.github.CST-Group:cst:5e79d5e4271d82193dda0e2826fef43d13b9f100' - api ':cst:0.5.1-full' + api 'com.github.CST-Group:cst:5e79d5e4271d82193dda0e2826fef43d13b9f100' + //api ':cst:0.5.1-full' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' testImplementation 'org.ros.rosjava_messages:rosjava_test_msgs:0.3.0' From 3ae08e72fb2eba1a0ea3b615d157e2f2fd46b5f9 Mon Sep 17 00:00:00 2001 From: Ricardo Gudwin Date: Tue, 13 Oct 2020 11:55:13 -0300 Subject: [PATCH 22/89] Changes to make tests pass in new JDK due to restrictions with just a unique constructor in tests --- .../unicamp/meca/models/ActionStepTest.java | 36 ++++------------- .../unicamp/meca/models/ActionStepTester.java | 40 +++++++++++++++++++ 2 files changed, 47 insertions(+), 29 deletions(-) create mode 100644 src/test/java/br/unicamp/meca/models/ActionStepTester.java diff --git a/src/test/java/br/unicamp/meca/models/ActionStepTest.java b/src/test/java/br/unicamp/meca/models/ActionStepTest.java index a01e785..d1b488b 100644 --- a/src/test/java/br/unicamp/meca/models/ActionStepTest.java +++ b/src/test/java/br/unicamp/meca/models/ActionStepTest.java @@ -1,17 +1,13 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ package br.unicamp.meca.models; + import br.unicamp.cst.core.entities.Memory; +import br.unicamp.meca.models.ActionStep; import java.util.List; -import static org.junit.Assert.assertEquals; -import org.junit.Test; -/** - * - * @author rgudwin +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. */ public class ActionStepTest extends ActionStep { @@ -32,22 +28,4 @@ public boolean stopCondition(List perceptions) { return(false); } - @Test - public void testActionStep() { - ActionStep as1 = new ActionStepTest(); - assertEquals(as1.getNumberOfParameters(),0); - ActionStep as2 = new ActionStepTest("TestAction"); - assertEquals(as2.getNumberOfParameters(),0); - assertEquals(as2.getActionId(),"TestAction"); - as2.setParameter("param", "value"); - assertEquals(as2.getNumberOfParameters(),1); - assertEquals(as2.getParameter("param"),"value"); - as2.setParameter("param", "value2"); - assertEquals(as2.getParameter("param"),"value2"); - as2.unsetParameter("param"); - assertEquals(as2.getNumberOfParameters(),0); - } - - - -} +} \ No newline at end of file diff --git a/src/test/java/br/unicamp/meca/models/ActionStepTester.java b/src/test/java/br/unicamp/meca/models/ActionStepTester.java new file mode 100644 index 0000000..0e7fd0e --- /dev/null +++ b/src/test/java/br/unicamp/meca/models/ActionStepTester.java @@ -0,0 +1,40 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package br.unicamp.meca.models; +import br.unicamp.cst.core.entities.Memory; +import java.util.List; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +/** + * + * @author rgudwin + */ +public class ActionStepTester { + + public void setUp() { + System.out.println("########## ActionStep TESTS ##########"); + } + + @Test + public void testActionStepTester() { + ActionStep as1 = new ActionStepTest(); + assertEquals(as1.getNumberOfParameters(),0); + ActionStep as2 = new ActionStepTest("TestAction"); + assertEquals(as2.getNumberOfParameters(),0); + assertEquals(as2.getActionId(),"TestAction"); + as2.setParameter("param", "value"); + assertEquals(as2.getNumberOfParameters(),1); + assertEquals(as2.getParameter("param"),"value"); + as2.setParameter("param", "value2"); + assertEquals(as2.getParameter("param"),"value2"); + as2.unsetParameter("param"); + assertEquals(as2.getNumberOfParameters(),0); + } + + + +} From 2df0ed39f3ef47cb90bfeef5456476067d6c1c81 Mon Sep 17 00:00:00 2001 From: Andre Paraense Date: Wed, 14 Oct 2020 19:02:10 +0100 Subject: [PATCH 23/89] Fixing mount meca mind --- .../java/br/unicamp/meca/mind/MecaMind.java | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/main/java/br/unicamp/meca/mind/MecaMind.java b/src/main/java/br/unicamp/meca/mind/MecaMind.java index a84f81e..4e286c8 100644 --- a/src/main/java/br/unicamp/meca/mind/MecaMind.java +++ b/src/main/java/br/unicamp/meca/mind/MecaMind.java @@ -274,23 +274,24 @@ private void mountMotivationalCodelets() { } private void mountActivityTrackingCodelet() { - - ArrayList perceptualIds = new ArrayList<>(); - for (PerceptualCodelet perception : perceptualCodelets) - perceptualIds.add(perception.getId()); - activityTrackingCodelet = new ActivityTrackingCodelet("ActivityTracking", perceptualIds); - registerCodelet(activityTrackingCodelet, "ActivityTracking"); - registerMemory(ACTION_SEQUENCE_PLAN_ID,"Plans"); - registerMemory(ACTION_SEQUENCE_PLAN_REQUEST_ID,"Plans"); - - if (activityTrackingCodelet != null && activityTrackingCodelet.getId() != null - && activityTrackingCodelet.getPerceptualCodeletsIds() != null) { - /* - * Inputs - */ - activityTrackingCodelet.addInput(actionSequencePlanMemoryContainer); - if(perceptualCodelets != null) { + if (activityTrackingCodelet != null && activityTrackingCodelet.getId() != null + && activityTrackingCodelet.getPerceptualCodeletsIds() != null) { + /* + * Inputs + */ + activityTrackingCodelet.addInput(actionSequencePlanMemoryContainer); + + if(perceptualCodelets != null) { + + ArrayList perceptualIds = new ArrayList<>(); + for (PerceptualCodelet perception : perceptualCodelets) + perceptualIds.add(perception.getId()); + activityTrackingCodelet = new ActivityTrackingCodelet("ActivityTracking", perceptualIds); + registerCodelet(activityTrackingCodelet, "ActivityTracking"); + registerMemory(ACTION_SEQUENCE_PLAN_ID,"Plans"); + registerMemory(ACTION_SEQUENCE_PLAN_REQUEST_ID,"Plans"); + for(PerceptualCodelet perceptualCodelet : perceptualCodelets) { if(perceptualCodelet != null && perceptualCodelet.getId() != null) { ArrayList perceptualCodeletsIds = activityTrackingCodelet.getPerceptualCodeletsIds(); From 7c2372dc0402d3d13c391442998e216d0c7a7ff1 Mon Sep 17 00:00:00 2001 From: Ricardo Gudwin Date: Mon, 19 Oct 2020 17:25:49 -0300 Subject: [PATCH 24/89] Change to use new CST --- build.gradle | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index 0d6e1c3..723dbf3 100644 --- a/build.gradle +++ b/build.gradle @@ -10,12 +10,9 @@ description = "The Multipurpose Enhanced Cognitive Architecture (MECA)" sourceCompatibility = 1.8 targetCompatibility = 1.8 -version = '0.3.0' +version = '0.4.0' repositories { - flatDir { - dirs '../cst/build/libs' - } mavenCentral() maven { url 'https://jitpack.io' } maven { @@ -30,8 +27,7 @@ repositories { } dependencies { - api 'com.github.CST-Group:cst:5e79d5e4271d82193dda0e2826fef43d13b9f100' - //api ':cst:0.5.1-full' + api 'com.github.CST-Group:cst:0.6.0' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' testImplementation 'org.ros.rosjava_messages:rosjava_test_msgs:0.3.0' @@ -57,7 +53,6 @@ task uberJar(type: Jar) { archiveClassifier = 'full' manifest { attributes( -// 'Class-Path': configurations.compile.collect { it.getName() }.join(' '), 'Class-Path': configurations.runtimeClasspath.files.collect { it.getName() }.join(' ') ) From 618d7b89588cfea52c1b1129d446a4652c1ed5f2 Mon Sep 17 00:00:00 2001 From: Andre Paraense Date: Tue, 20 Oct 2020 15:23:18 +0100 Subject: [PATCH 25/89] Bumping version --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index df1c746..8d63454 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Note: This library is still under development, and some concepts or features mig ``` dependencies { ... - implementation 'com.github.CST-Group:meca:0.3.0' + implementation 'com.github.CST-Group:meca:0.4.0' } ``` @@ -53,7 +53,7 @@ Sometimes, the version number (tag) in this README gets out of date, as maintain com.github.CST-Group meca - 0.3.0 + 0.4.0 ``` From 43ad6633a4f658e6674d543037797da99b6e9dbc Mon Sep 17 00:00:00 2001 From: Ricardo Gudwin Date: Tue, 20 Oct 2020 17:20:38 -0300 Subject: [PATCH 26/89] Changes to correct mistakes introduced in 0.4.0 --- build.gradle | 2 +- .../java/br/unicamp/meca/mind/MecaMind.java | 35 ++++++++++--------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/build.gradle b/build.gradle index 723dbf3..581fe96 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ description = "The Multipurpose Enhanced Cognitive Architecture (MECA)" sourceCompatibility = 1.8 targetCompatibility = 1.8 -version = '0.4.0' +version = '0.4.1' repositories { mavenCentral() diff --git a/src/main/java/br/unicamp/meca/mind/MecaMind.java b/src/main/java/br/unicamp/meca/mind/MecaMind.java index 4e286c8..ae7f88a 100644 --- a/src/main/java/br/unicamp/meca/mind/MecaMind.java +++ b/src/main/java/br/unicamp/meca/mind/MecaMind.java @@ -274,24 +274,25 @@ private void mountMotivationalCodelets() { } private void mountActivityTrackingCodelet() { - - if (activityTrackingCodelet != null && activityTrackingCodelet.getId() != null + + if (perceptualCodelets != null) { + ArrayList perceptualIds = new ArrayList<>(); + for (PerceptualCodelet perception : perceptualCodelets) + perceptualIds.add(perception.getId()); + activityTrackingCodelet = new ActivityTrackingCodelet("ActivityTracking", perceptualIds); + registerCodelet(activityTrackingCodelet, "ActivityTracking"); + registerMemory(ACTION_SEQUENCE_PLAN_ID,"Plans"); + registerMemory(ACTION_SEQUENCE_PLAN_REQUEST_ID,"Plans"); + } + + if (activityTrackingCodelet != null && activityTrackingCodelet.getId() != null && activityTrackingCodelet.getPerceptualCodeletsIds() != null) { - /* - * Inputs - */ - activityTrackingCodelet.addInput(actionSequencePlanMemoryContainer); - - if(perceptualCodelets != null) { - - ArrayList perceptualIds = new ArrayList<>(); - for (PerceptualCodelet perception : perceptualCodelets) - perceptualIds.add(perception.getId()); - activityTrackingCodelet = new ActivityTrackingCodelet("ActivityTracking", perceptualIds); - registerCodelet(activityTrackingCodelet, "ActivityTracking"); - registerMemory(ACTION_SEQUENCE_PLAN_ID,"Plans"); - registerMemory(ACTION_SEQUENCE_PLAN_REQUEST_ID,"Plans"); - + /* + * Inputs + */ + activityTrackingCodelet.addInput(actionSequencePlanMemoryContainer); + + if(perceptualCodelets != null) { for(PerceptualCodelet perceptualCodelet : perceptualCodelets) { if(perceptualCodelet != null && perceptualCodelet.getId() != null) { ArrayList perceptualCodeletsIds = activityTrackingCodelet.getPerceptualCodeletsIds(); From 017948e194437a41b5038a17628bdd28622009f7 Mon Sep 17 00:00:00 2001 From: Andre Paraense Date: Tue, 20 Oct 2020 22:58:43 +0100 Subject: [PATCH 27/89] Bumping version --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8d63454..d867ba3 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Note: This library is still under development, and some concepts or features mig ``` dependencies { ... - implementation 'com.github.CST-Group:meca:0.4.0' + implementation 'com.github.CST-Group:meca:0.4.1' } ``` @@ -53,7 +53,7 @@ Sometimes, the version number (tag) in this README gets out of date, as maintain com.github.CST-Group meca - 0.4.0 + 0.4.1 ``` From b26bffcb9b856d604369368cf3c287a071f190b8 Mon Sep 17 00:00:00 2001 From: Andre Paraense Date: Mon, 9 Nov 2020 15:11:40 +0000 Subject: [PATCH 28/89] CST update to improve disconnected codelet message --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 581fe96..184b068 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ description = "The Multipurpose Enhanced Cognitive Architecture (MECA)" sourceCompatibility = 1.8 targetCompatibility = 1.8 -version = '0.4.1' +version = '0.4.2' repositories { mavenCentral() @@ -27,7 +27,7 @@ repositories { } dependencies { - api 'com.github.CST-Group:cst:0.6.0' + api 'com.github.CST-Group:cst:14a3bd3' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' testImplementation 'org.ros.rosjava_messages:rosjava_test_msgs:0.3.0' From f2318bfc3b96a207593a8125b077e571e91d9387 Mon Sep 17 00:00:00 2001 From: Andre Paraense Date: Mon, 9 Nov 2020 17:38:19 +0000 Subject: [PATCH 29/89] Update CST version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 184b068..0a07fa5 100644 --- a/build.gradle +++ b/build.gradle @@ -27,7 +27,7 @@ repositories { } dependencies { - api 'com.github.CST-Group:cst:14a3bd3' + api 'com.github.CST-Group:cst:0.6.1' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' testImplementation 'org.ros.rosjava_messages:rosjava_test_msgs:0.3.0' From fa2605c141989600e1e9661a4318d089f532579b Mon Sep 17 00:00:00 2001 From: Andre Paraense Date: Mon, 9 Nov 2020 17:43:56 +0000 Subject: [PATCH 30/89] Update README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d867ba3..50ed27b 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Note: This library is still under development, and some concepts or features mig ``` dependencies { ... - implementation 'com.github.CST-Group:meca:0.4.1' + implementation 'com.github.CST-Group:meca:0.4.2' } ``` @@ -53,7 +53,7 @@ Sometimes, the version number (tag) in this README gets out of date, as maintain com.github.CST-Group meca - 0.4.1 + 0.4.2 ``` From a7016460a8569b97ef89541b3ff5f744f2202975 Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Tue, 17 Nov 2020 14:16:07 -0300 Subject: [PATCH 31/89] Changes to ActivityCodelet and ActivityTrackingCodelet (and also ActionSequencePlan and ActionStep) to include a way for executed ActionSteps to conclude the plan, after the ActivityTrackingCodelet has advanced to the following ActionStep. This is necessary, usually, to set the MotorCodelet to null, after the ActionStep was concluded. --- README.md | 2 +- build.gradle | 2 +- .../meca/models/ActionSequencePlan.java | 32 +++- .../br/unicamp/meca/models/ActionStep.java | 2 + .../system1/codelets/ActivityCodelet.java | 53 +++++- .../codelets/ActivityTrackingCodelet.java | 18 ++- .../mind/action/Test1ActivityCodelet.java | 6 + .../mind/action/Test2ActivityCodelet.java | 5 + .../mind/action/Test3ActivityCodelet.java | 5 + .../meca/mind/action/TestActivityCodelet.java | 152 ++++++++++++++++++ .../tracking/testActivityTrackingCodelet.java | 115 +++++++++++++ .../meca/models/ActionSequencePlanTest.java | 83 +++++++++- .../unicamp/meca/models/ActionStepTest.java | 5 + .../unicamp/meca/models/ActionStepTester.java | 2 - 14 files changed, 458 insertions(+), 24 deletions(-) create mode 100644 src/test/java/br/unicamp/meca/mind/action/TestActivityCodelet.java create mode 100644 src/test/java/br/unicamp/meca/mind/tracking/testActivityTrackingCodelet.java diff --git a/README.md b/README.md index 50ed27b..813e9d5 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Note: This library is still under development, and some concepts or features mig ``` dependencies { ... - implementation 'com.github.CST-Group:meca:0.4.2' + implementation 'com.github.CST-Group:meca:0.4.3' } ``` diff --git a/build.gradle b/build.gradle index 0a07fa5..17cfc0c 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ description = "The Multipurpose Enhanced Cognitive Architecture (MECA)" sourceCompatibility = 1.8 targetCompatibility = 1.8 -version = '0.4.2' +version = '0.4.3' repositories { mavenCentral() diff --git a/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java b/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java index ac93c81..2e183fc 100644 --- a/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java +++ b/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java @@ -44,15 +44,27 @@ public ActionSequencePlan(ActionStep[] actionIdSequence) { } /** - * Returns the id of the current ActionFromPlanningCodelet to be undertaken in the plan. + * Returns the ActionStep of the current ActionFromPlanningCodelet to be undertaken in the plan. * * @return currentActionId */ public ActionStep getCurrentActionStep() { return actionIdSequence[currentActionIdIndex]; } + + /** + * Returns the ActionStep of the last ActionFromPlanningCodelet to be undertaken in the plan, or null if it is the first step. + * + * @return currentActionId + */ + public ActionStep getLastActionStep() { + if (currentActionIdIndex == 0) return(actionIdSequence[actionIdSequence.length-1]); + else return actionIdSequence[currentActionIdIndex-1]; + } /** + * get the array of ActionSteps which are related to the ActionSequencePlan + * * @return the actionIdSequence */ public ActionStep[] getActionStepSequence() { @@ -60,6 +72,8 @@ public ActionStep[] getActionStepSequence() { } /** + * Forces a new actionStepSequence + * * @param actionIdSequence the actionIdSequence to set */ public void setActionStepSequence(ActionStep[] actionIdSequence) { @@ -80,13 +94,18 @@ public void setCurrentActionIdIndex(int currentActionIdIndex) { this.currentActionIdIndex = currentActionIdIndex; } + /** + * Go to next action. If the action is the last in the plan, go to the first action + */ public void gotoNextAction() { + actionIdSequence[currentActionIdIndex].executed = true; if (currentActionIdIndex < actionIdSequence.length-1) currentActionIdIndex++; + else currentActionIdIndex = 0; } public String toString() { - String output = "{ "; + String output = "{"; int i=0; for (ActionStep a : actionIdSequence) { output += a.toString(); @@ -97,4 +116,13 @@ public String toString() { output += "}"; return(output); } + + /** + * Reset the plan. Set all the action steps executed flag to false. + */ + public void resetPlan() { + for (ActionStep as : actionIdSequence) { + as.executed = false; + } + } } diff --git a/src/main/java/br/unicamp/meca/models/ActionStep.java b/src/main/java/br/unicamp/meca/models/ActionStep.java index 1dcb37d..d02b682 100644 --- a/src/main/java/br/unicamp/meca/models/ActionStep.java +++ b/src/main/java/br/unicamp/meca/models/ActionStep.java @@ -24,6 +24,8 @@ public abstract class ActionStep { String actionId; Map parameters; + public boolean needsConclusion = false; + public boolean executed = false; public ActionStep() { actionId = ""; diff --git a/src/main/java/br/unicamp/meca/system1/codelets/ActivityCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/ActivityCodelet.java index f5b63fc..08a354a 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/ActivityCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/ActivityCodelet.java @@ -93,7 +93,8 @@ public void accessMemoryObjects() { for(String perceptualCodeletId : perceptualCodeletsIds) { Memory perceptualMemory = this.getInput(perceptualCodeletId, index); - perceptualMemories.add(perceptualMemory); + if (perceptualMemory != null) + perceptualMemories.add(perceptualMemory); } } } @@ -107,7 +108,8 @@ public void accessMemoryObjects() { for(String motivationalCodeletsId : motivationalCodeletsIds) { Memory inputDrive = this.getInput(motivationalCodeletsId + "Drive"); - driveMemories.add(inputDrive); + if (inputDrive != null) + driveMemories.add(inputDrive); } } } @@ -168,11 +170,21 @@ public void calculateActivation() { public void proc() { if(actionSequencePlanMemoryContainer != null && actionSequencePlanMemoryContainer.getI() != null && actionSequencePlanMemoryContainer.getI() instanceof ActionSequencePlan) { ActionSequencePlan actionSequencePlan = (ActionSequencePlan) actionSequencePlanMemoryContainer.getI(); - String currentActionId = actionSequencePlan.getCurrentActionStep().getActionId(); + ActionStep currentAction = actionSequencePlan.getCurrentActionStep(); + String currentActionId = currentAction.getActionId(); - if(currentActionId != null && currentActionId.equalsIgnoreCase(id)) { + if(currentActionId != null && currentActionId.equalsIgnoreCase(id) && currentAction.executed == false) { proc(perceptualMemories, broadcastMemory, motorMemory); } + else { + ActionStep lastActionStep = actionSequencePlan.getLastActionStep(); + String lastActionId = lastActionStep.getActionId(); + if (lastActionStep != null && lastActionStep.needsConclusion && lastActionId.equalsIgnoreCase(id)) { + System.out.println("CurrentID: "+actionSequencePlan.getCurrentActionIdIndex()+" CurrentActionStep: "+currentActionId+" LastActionStep: "+lastActionStep.getActionId()); + doConclusion(perceptualMemories, broadcastMemory, motorMemory); + lastActionStep.needsConclusion = false; + } + } }else { proc(perceptualMemories, broadcastMemory, motorMemory); } @@ -189,6 +201,19 @@ public void proc() { * the output motor memory. */ public abstract void proc(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory); + + /** + * Method to be called to do the Conclusion of an ActionStep, after its activities are over. + * Similar to the proc method, but to be called one last time to clean whatever needs to be cleaned at the motorMemory + * + * @param perceptualMemories + * the input memories coming from perception. + * @param broadcastMemory + * the input memory coming from the conscious planner broadcast. + * @param motorMemory + * the output motor memory. + */ + public abstract void doConclusion(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory); /** * Returns the id of the Soar Codelet whose outputs will be read by this @@ -278,4 +303,24 @@ public void setMotorCodeletId(String motorCodeletId) { public ArrayList getMotivationalCodeletsIds() { return motivationalCodeletsIds; } + + public ArrayList getPerceptionMemories() { + return(perceptualMemories); + } + + public ArrayList getDriveMemories() { + return(driveMemories); + } + + public Memory getBroadcastMemory() { + return(broadcastMemory); + } + + public Memory getActionSequencePlanMemoryContainer() { + return(actionSequencePlanMemoryContainer); + } + + public Memory getMotorMemory() { + return(motorMemory); + } } diff --git a/src/main/java/br/unicamp/meca/system1/codelets/ActivityTrackingCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/ActivityTrackingCodelet.java index 62e4cbf..a722b78 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/ActivityTrackingCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/ActivityTrackingCodelet.java @@ -100,18 +100,22 @@ public void trackActionSequencePlan(ArrayList perceptualMemories, Action perceptualMemories != null && perceptualMemories.size() > 0) { ActionStep currentActionStep = actionSequencePlan.getCurrentActionStep(); - if (currentActionStep.stopCondition(perceptualMemories)) { - actionSequencePlan.gotoNextAction(); - } + ActionStep lastActionStep = actionSequencePlan.getLastActionStep(); + if (actionSequencePlan.getCurrentActionIdIndex() == 0 || lastActionStep.needsConclusion == false) { + if (currentActionStep != null && currentActionStep.executed == false && currentActionStep.stopCondition(perceptualMemories)) { + currentActionStep.needsConclusion = true; + actionSequencePlan.gotoNextAction(); + } + } } } @Override public void proc() { - - actionSequencePlan = (ActionSequencePlan) actionSequencePlanMemoryContainer.getI(); - - trackActionSequencePlan(perceptualMemories, actionSequencePlan); + if (actionSequencePlanMemoryContainer != null) { + actionSequencePlan = (ActionSequencePlan) actionSequencePlanMemoryContainer.getI(); + trackActionSequencePlan(perceptualMemories, actionSequencePlan); + } } /** diff --git a/src/test/java/br/unicamp/meca/mind/action/Test1ActivityCodelet.java b/src/test/java/br/unicamp/meca/mind/action/Test1ActivityCodelet.java index f61e0a2..3377e91 100644 --- a/src/test/java/br/unicamp/meca/mind/action/Test1ActivityCodelet.java +++ b/src/test/java/br/unicamp/meca/mind/action/Test1ActivityCodelet.java @@ -26,6 +26,12 @@ public Test1ActivityCodelet(String id, ArrayList perceptualCodeletsIds, ArrayList motivationalCodeletsIds, String motorCodeletId, String soarCodeletId) { super(id, perceptualCodeletsIds, motivationalCodeletsIds, motorCodeletId, soarCodeletId); } + + @Override + public void doConclusion(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory) { + System.out.println("Concluding Test1Activity"); + ((MemoryContainer) motorMemory).setI("Test1Activity - concluded",getActivation(),id); + } @Override public void proc(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory) { diff --git a/src/test/java/br/unicamp/meca/mind/action/Test2ActivityCodelet.java b/src/test/java/br/unicamp/meca/mind/action/Test2ActivityCodelet.java index 9d78e85..e0d8d26 100644 --- a/src/test/java/br/unicamp/meca/mind/action/Test2ActivityCodelet.java +++ b/src/test/java/br/unicamp/meca/mind/action/Test2ActivityCodelet.java @@ -26,6 +26,11 @@ public Test2ActivityCodelet(String id, ArrayList perceptualCodeletsIds, ArrayList motivationalCodeletsIds, String motorCodeletId, String soarCodeletId) { super(id, perceptualCodeletsIds, motivationalCodeletsIds, motorCodeletId, soarCodeletId); } + + @Override + public void doConclusion(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory) { + System.out.println("Concluding Test2Activity"); + } @Override public void proc(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory) { diff --git a/src/test/java/br/unicamp/meca/mind/action/Test3ActivityCodelet.java b/src/test/java/br/unicamp/meca/mind/action/Test3ActivityCodelet.java index 66d7524..8cd68fd 100644 --- a/src/test/java/br/unicamp/meca/mind/action/Test3ActivityCodelet.java +++ b/src/test/java/br/unicamp/meca/mind/action/Test3ActivityCodelet.java @@ -26,6 +26,11 @@ public Test3ActivityCodelet(String id, ArrayList perceptualCodeletsIds, ArrayList motivationalCodeletsIds, String motorCodeletId, String soarCodeletId) { super(id, perceptualCodeletsIds, motivationalCodeletsIds, motorCodeletId, soarCodeletId); } + + @Override + public void doConclusion(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory) { + System.out.println("Concluding Test3Activity"); + } @Override public void proc(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory) { diff --git a/src/test/java/br/unicamp/meca/mind/action/TestActivityCodelet.java b/src/test/java/br/unicamp/meca/mind/action/TestActivityCodelet.java new file mode 100644 index 0000000..51a724c --- /dev/null +++ b/src/test/java/br/unicamp/meca/mind/action/TestActivityCodelet.java @@ -0,0 +1,152 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package br.unicamp.meca.mind.action; + +import br.unicamp.cst.core.entities.MemoryContainer; +import br.unicamp.cst.core.entities.MemoryObject; +import br.unicamp.meca.mind.MecaMind; +import br.unicamp.meca.mind.motor.TestMotorCodelet; +import br.unicamp.meca.mind.perceptual.TestPerceptualCodelet; +import br.unicamp.meca.mind.sensory.TestPerceptionSensoryCodelet; +import br.unicamp.meca.models.ActionSequencePlan; +import br.unicamp.meca.models.ActionStep; +import br.unicamp.meca.models.ActionStepTest; +import br.unicamp.meca.system1.codelets.ActivityCodelet; +import br.unicamp.meca.system1.codelets.MotorCodelet; +import br.unicamp.meca.system1.codelets.PerceptualCodelet; +import br.unicamp.meca.system1.codelets.SensoryCodelet; +import java.util.ArrayList; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +/** + * + * @author rgudwin + */ +public class TestActivityCodelet { + + SensoryCodelet sc; + PerceptualCodelet pc; + ActivityCodelet ac; + + @Test + public void testAccessMemoryObjects() { + ArrayList lsc = new ArrayList(); + lsc.add("m1"); + lsc.add("m2"); + lsc.add("m3"); + ac = new Test1ActivityCodelet("teste",lsc,lsc,null,null); + ac.accessMemoryObjects(); + assertEquals(ac.getPerceptionMemories().size(),0); + MemoryObject mo = new MemoryObject(); + mo.setType("m1"); + ac.addInput(mo); + mo = new MemoryObject(); + mo.setType("m2"); + ac.addInput(mo); + mo = new MemoryObject(); + mo.setType("m3"); + ac.addInput(mo); + ac.accessMemoryObjects(); + assertEquals(ac.getPerceptionMemories().size(),3); + mo = new MemoryObject(); + mo.setType("m1Drive"); + ac.addInput(mo); + mo = new MemoryObject(); + mo.setType("m2Drive"); + ac.addInput(mo); + mo = new MemoryObject(); + mo.setType("m3Drive"); + ac.addInput(mo); + ac.accessMemoryObjects(); + assertEquals(ac.getDriveMemories().size(),3); + ac = new Test1ActivityCodelet("teste",null,null,"motor","soar"); + mo = new MemoryObject(); + mo.setType("motor"); + ac.addOutput(mo); + ac.accessMemoryObjects(); + assertEquals(ac.getMotorMemory(),mo); + mo = new MemoryObject(); + mo.setType("soar"); + ac.addBroadcast(mo); + ac.accessMemoryObjects(); + assertEquals(ac.getBroadcastMemory(),mo); + MemoryContainer mc = new MemoryContainer(); + mc.setType(MecaMind.ACTION_SEQUENCE_PLAN_ID); + ac.addInput(mc); + ac.accessMemoryObjects(); + assertEquals(ac.getActionSequencePlanMemoryContainer(),mc); + } + + @Test + public void testActivityCodelet() { + sc = new TestPerceptionSensoryCodelet("sensory"); + ArrayList lsc = new ArrayList(); + lsc.add("sensory"); + pc = new TestPerceptualCodelet("perception",lsc); + lsc = new ArrayList(); + ac = new Test1ActivityCodelet("teste",null,null,null,null); + ac.accessMemoryObjects(); + ac.proc(); + ac.calculateActivation(); + + ac = new Test1ActivityCodelet("teste",lsc,lsc,null,null); + ac.accessMemoryObjects(); + ac.proc(); + ac.calculateActivation(); + + ac = new Test1ActivityCodelet("teste",lsc,lsc,"motor",null); + ac.accessMemoryObjects(); + ac.proc(); + ac.calculateActivation(); + + MotorCodelet mc = new TestMotorCodelet("motor"); + ac.accessMemoryObjects(); + ac.proc(); + ac.calculateActivation(); + + } + + @Test + public void testCalculateActivation() { + ArrayList lsc = new ArrayList(); + lsc.add("m1"); + lsc.add("m2"); + lsc.add("m3"); + ac = new Test1ActivityCodelet("teste",null,lsc,null,null); + MemoryObject mo = new MemoryObject(); + mo.setType("m1Drive"); + mo.setEvaluation(0.5); + ac.addInput(mo); + mo = new MemoryObject(); + mo.setType("m2Drive"); + mo.setEvaluation(0.6); + ac.addInput(mo); + mo = new MemoryObject(); + mo.setType("m3Drive"); + ac.addInput(mo); + mo.setEvaluation(0.8); + ac.accessMemoryObjects(); + ac.calculateActivation(); + double presumedActivation = (0.5+0.6+0.8)/3; + assertEquals(ac.getActivation(),presumedActivation,0); + MemoryContainer mc = new MemoryContainer(); + mc.setType(MecaMind.ACTION_SEQUENCE_PLAN_ID); + ActionStep as[] = new ActionStep[1]; + ActionSequencePlan asp = new ActionSequencePlan(as); + mc.setI(asp,0.2); + ac.addInput(mc); + ac.accessMemoryObjects(); + ac.calculateActivation(); + // Because the ActionStep is null, the evaluation is 0 + assertEquals(ac.getActivation(),0,0); + as[0] = new ActionStepTest("teste"); + // Now that there is an action step with the same name as the ActivityCodelet, it should be 0.2 + ac.calculateActivation(); + assertEquals(ac.getActivation(),0.2,0); + } + +} diff --git a/src/test/java/br/unicamp/meca/mind/tracking/testActivityTrackingCodelet.java b/src/test/java/br/unicamp/meca/mind/tracking/testActivityTrackingCodelet.java new file mode 100644 index 0000000..e94791f --- /dev/null +++ b/src/test/java/br/unicamp/meca/mind/tracking/testActivityTrackingCodelet.java @@ -0,0 +1,115 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package br.unicamp.meca.mind.tracking; + +import br.unicamp.cst.core.entities.MemoryContainer; +import br.unicamp.cst.core.entities.MemoryObject; +import br.unicamp.meca.mind.MecaMind; +import br.unicamp.meca.models.ActionSequencePlan; +import br.unicamp.meca.models.ActionStep; +import br.unicamp.meca.models.ActionStepTest; +import br.unicamp.meca.system1.codelets.ActivityTrackingCodelet; +import java.util.ArrayList; +import java.util.List; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +/** + * + * @author rgudwin + */ +public class testActivityTrackingCodelet { + ActivityTrackingCodelet atc; + + @Test + public void testActivityTrackingCodelet() { + atc = new ActivityTrackingCodelet("tracking",null); + atc.accessMemoryObjects(); + atc.calculateActivation(); + // This tests the case when there is still no sequence plan to be tracked + atc.proc(); + // Now let's introduce an empty perception list + ArrayList lop = new ArrayList(); + atc = new ActivityTrackingCodelet("tracking",lop); + atc.accessMemoryObjects(); + atc.calculateActivation(); + atc.proc(); + // Now let's define an inexistent perception + lop.add("perception"); + atc.accessMemoryObjects(); + atc.calculateActivation(); + atc.proc(); + // Now, still without perception, let's introduce a sequence plan + MemoryContainer mc = new MemoryContainer(); + mc.setType(MecaMind.ACTION_SEQUENCE_PLAN_ID); + atc.addInput(mc); + atc.accessMemoryObjects(); + // Now there is a memory object, but still no sequence plan + atc.accessMemoryObjects(); + atc.calculateActivation(); + atc.proc(); + // Now let's include a plan, but still without any action step + ActionStep as[] = new ActionStep[3]; + ActionSequencePlan asp = new ActionSequencePlan(as); + mc.setI(asp,0.2); + atc.accessMemoryObjects(); + atc.calculateActivation(); + atc.proc(); + // Finally, let's include the action steps + ActionStep as1 = new ActionStepTest("tracking"); + as[0] = as1; + ActionStep as2 = new ActionStepTest("tracking"); + as[1] = as2; + ActionStep as3 = new ActionStepTest("tracking"); + as[2] = as3; + atc.accessMemoryObjects(); + atc.calculateActivation(); + atc.proc(); + assertEquals(asp.getCurrentActionIdIndex(),0); + // Now let's introduce a Perception Memory to track + // And now finally let's provide an existent perception, still without info + MemoryObject per = new MemoryObject(); + per.setType("perception"); + atc = new ActivityTrackingCodelet("tracking",lop); + atc.addInput(per); + atc.addInput(mc); + atc.accessMemoryObjects(); + atc.calculateActivation(); + atc.proc(); + assertEquals(asp.getCurrentActionIdIndex(),0); + // Now, let's create the conditions for the codelet decide to move to its 2nd step + per.setEvaluation(1.0); + atc.addInput(per); + //as[0].needsConclusion = true; + atc.accessMemoryObjects(); + atc.calculateActivation(); + assertEquals(as[0].executed,false); + atc.proc(); + // Now, because there are conditions for move to the second step of the plan, the index should be 1 + assertEquals(as[0].executed,true); + // Because the ActionStep 0 was executed, now it needs conclusion + assertEquals(as[0].needsConclusion,true); + assertEquals(asp.getCurrentActionIdIndex(),1); + assertEquals(as[1].executed,false); + atc.proc(); + // Now let's play a little ... because the conclusion didn't come, this proc will not move to the 3rd action step + assertEquals(as[1].executed,false); + // Let's then conclude the action step 0 e see what happens + as[0].needsConclusion = false; + atc.proc(); + // Now, this allows the execution of action step 1 + assertEquals(as[1].executed,true); + assertEquals(asp.getCurrentActionIdIndex(),2); + assertEquals(as[2].executed,false); + assertEquals(as[1].needsConclusion,true); + as[1].needsConclusion = false; + atc.proc(); + assertEquals(as[2].needsConclusion,true); + assertEquals(asp.getCurrentActionIdIndex(),0); + assertEquals(as[2].executed,true); + } + +} diff --git a/src/test/java/br/unicamp/meca/models/ActionSequencePlanTest.java b/src/test/java/br/unicamp/meca/models/ActionSequencePlanTest.java index 971d874..823b33f 100644 --- a/src/test/java/br/unicamp/meca/models/ActionSequencePlanTest.java +++ b/src/test/java/br/unicamp/meca/models/ActionSequencePlanTest.java @@ -12,22 +12,91 @@ * */ public class ActionSequencePlanTest { + + ActionStep as1 = new ActionStepTest("Land"); + ActionStep as2 = new ActionStepTest("Stop"); + ActionSequencePlan landAndStopSequencePlan = new ActionSequencePlan(new ActionStep[] {as1,as2}); public void setUp() { System.out.println("########## Action Sequence Plan TESTS ##########"); } + + @Test + public void testGetCurrentActionIdIndex() { + landAndStopSequencePlan.setCurrentActionIdIndex(0); + int currentStep = landAndStopSequencePlan.getCurrentActionIdIndex(); + assertEquals(currentStep,0); + landAndStopSequencePlan.setCurrentActionIdIndex(1); + currentStep = landAndStopSequencePlan.getCurrentActionIdIndex(); + assertEquals(currentStep,1); + } @Test public void testGetCurrentActionId() { - - ActionStep as1 = new ActionStepTest("Land"); - ActionStep as2 = new ActionStepTest("Stop"); - ActionSequencePlan landAndStopSequencePlan = new ActionSequencePlan(new ActionStep[] {as1,as2}); - + landAndStopSequencePlan.setCurrentActionIdIndex(0); assertEquals(landAndStopSequencePlan.getCurrentActionStep().getActionId(), "Land"); - + landAndStopSequencePlan.setCurrentActionIdIndex(1); - assertEquals(landAndStopSequencePlan.getCurrentActionStep().getActionId(), "Stop"); } + + @Test + public void testGetCurrentActionStep() { + landAndStopSequencePlan.setCurrentActionIdIndex(0); + ActionStep as = landAndStopSequencePlan.getCurrentActionStep(); + assertEquals(as,as1); + landAndStopSequencePlan.setCurrentActionIdIndex(1); + as = landAndStopSequencePlan.getCurrentActionStep(); + assertEquals(as,as2); + } + + @Test + public void testLastActionStep() { + landAndStopSequencePlan.setCurrentActionIdIndex(0); + ActionStep lastAS = landAndStopSequencePlan.getLastActionStep(); + assertEquals(lastAS,as2); + assertEquals(lastAS.executed,false); + assertEquals(lastAS.needsConclusion,false); + + landAndStopSequencePlan.setCurrentActionIdIndex(1); + lastAS = landAndStopSequencePlan.getLastActionStep(); + assertEquals(lastAS,as1); + assertEquals(lastAS.executed,false); + assertEquals(lastAS.needsConclusion,false); + } + + @Test + public void testGoToNextAction() { + landAndStopSequencePlan.setCurrentActionIdIndex(0); + ActionStep as = landAndStopSequencePlan.getCurrentActionStep(); + assertEquals(as,as1); + assertEquals(as1.executed,false); + + landAndStopSequencePlan.gotoNextAction(); + as = landAndStopSequencePlan.getCurrentActionStep(); + assertEquals(as,as2); + assertEquals(as1.executed,true); + assertEquals(as2.executed,false); + landAndStopSequencePlan.gotoNextAction(); + as = landAndStopSequencePlan.getCurrentActionStep(); + assertEquals(as,as1); + assertEquals(as2.executed,true); + } + + @Test + public void testResetPlan() { + as1.executed = true; + as2.executed = true; + landAndStopSequencePlan.resetPlan(); + for (ActionStep ass : landAndStopSequencePlan.getActionStepSequence()) { + assertEquals(ass.executed,false); + assertEquals(ass.needsConclusion,false); + } + } + + @Test + public void testToString() { + String s = landAndStopSequencePlan.toString(); + assertEquals(s,"{Land, Stop}"); + } } diff --git a/src/test/java/br/unicamp/meca/models/ActionStepTest.java b/src/test/java/br/unicamp/meca/models/ActionStepTest.java index d1b488b..488e3f1 100644 --- a/src/test/java/br/unicamp/meca/models/ActionStepTest.java +++ b/src/test/java/br/unicamp/meca/models/ActionStepTest.java @@ -25,6 +25,11 @@ public void setUp() { @Override public boolean stopCondition(List perceptions) { + if (perceptions != null && perceptions.size() > 0) { + Memory perceptionMemory = perceptions.get(0); + if (perceptionMemory != null && perceptionMemory.getEvaluation() > 0.5) return(true); + else return(false); + } return(false); } diff --git a/src/test/java/br/unicamp/meca/models/ActionStepTester.java b/src/test/java/br/unicamp/meca/models/ActionStepTester.java index 0e7fd0e..aae2313 100644 --- a/src/test/java/br/unicamp/meca/models/ActionStepTester.java +++ b/src/test/java/br/unicamp/meca/models/ActionStepTester.java @@ -4,8 +4,6 @@ * and open the template in the editor. */ package br.unicamp.meca.models; -import br.unicamp.cst.core.entities.Memory; -import java.util.List; import static org.junit.Assert.assertEquals; import org.junit.Test; From d1ceedc5d7ccc6e05048d6da552d92649b62f8c5 Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Tue, 17 Nov 2020 14:16:07 -0300 Subject: [PATCH 32/89] Elimination of a comment --- README.md | 2 +- build.gradle | 2 +- .../meca/models/ActionSequencePlan.java | 32 +++- .../br/unicamp/meca/models/ActionStep.java | 2 + .../system1/codelets/ActivityCodelet.java | 52 +++++- .../codelets/ActivityTrackingCodelet.java | 18 ++- .../mind/action/Test1ActivityCodelet.java | 6 + .../mind/action/Test2ActivityCodelet.java | 5 + .../mind/action/Test3ActivityCodelet.java | 5 + .../meca/mind/action/TestActivityCodelet.java | 152 ++++++++++++++++++ .../tracking/testActivityTrackingCodelet.java | 115 +++++++++++++ .../meca/models/ActionSequencePlanTest.java | 83 +++++++++- .../unicamp/meca/models/ActionStepTest.java | 5 + .../unicamp/meca/models/ActionStepTester.java | 2 - 14 files changed, 457 insertions(+), 24 deletions(-) create mode 100644 src/test/java/br/unicamp/meca/mind/action/TestActivityCodelet.java create mode 100644 src/test/java/br/unicamp/meca/mind/tracking/testActivityTrackingCodelet.java diff --git a/README.md b/README.md index 50ed27b..813e9d5 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Note: This library is still under development, and some concepts or features mig ``` dependencies { ... - implementation 'com.github.CST-Group:meca:0.4.2' + implementation 'com.github.CST-Group:meca:0.4.3' } ``` diff --git a/build.gradle b/build.gradle index 0a07fa5..17cfc0c 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ description = "The Multipurpose Enhanced Cognitive Architecture (MECA)" sourceCompatibility = 1.8 targetCompatibility = 1.8 -version = '0.4.2' +version = '0.4.3' repositories { mavenCentral() diff --git a/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java b/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java index ac93c81..2e183fc 100644 --- a/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java +++ b/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java @@ -44,15 +44,27 @@ public ActionSequencePlan(ActionStep[] actionIdSequence) { } /** - * Returns the id of the current ActionFromPlanningCodelet to be undertaken in the plan. + * Returns the ActionStep of the current ActionFromPlanningCodelet to be undertaken in the plan. * * @return currentActionId */ public ActionStep getCurrentActionStep() { return actionIdSequence[currentActionIdIndex]; } + + /** + * Returns the ActionStep of the last ActionFromPlanningCodelet to be undertaken in the plan, or null if it is the first step. + * + * @return currentActionId + */ + public ActionStep getLastActionStep() { + if (currentActionIdIndex == 0) return(actionIdSequence[actionIdSequence.length-1]); + else return actionIdSequence[currentActionIdIndex-1]; + } /** + * get the array of ActionSteps which are related to the ActionSequencePlan + * * @return the actionIdSequence */ public ActionStep[] getActionStepSequence() { @@ -60,6 +72,8 @@ public ActionStep[] getActionStepSequence() { } /** + * Forces a new actionStepSequence + * * @param actionIdSequence the actionIdSequence to set */ public void setActionStepSequence(ActionStep[] actionIdSequence) { @@ -80,13 +94,18 @@ public void setCurrentActionIdIndex(int currentActionIdIndex) { this.currentActionIdIndex = currentActionIdIndex; } + /** + * Go to next action. If the action is the last in the plan, go to the first action + */ public void gotoNextAction() { + actionIdSequence[currentActionIdIndex].executed = true; if (currentActionIdIndex < actionIdSequence.length-1) currentActionIdIndex++; + else currentActionIdIndex = 0; } public String toString() { - String output = "{ "; + String output = "{"; int i=0; for (ActionStep a : actionIdSequence) { output += a.toString(); @@ -97,4 +116,13 @@ public String toString() { output += "}"; return(output); } + + /** + * Reset the plan. Set all the action steps executed flag to false. + */ + public void resetPlan() { + for (ActionStep as : actionIdSequence) { + as.executed = false; + } + } } diff --git a/src/main/java/br/unicamp/meca/models/ActionStep.java b/src/main/java/br/unicamp/meca/models/ActionStep.java index 1dcb37d..d02b682 100644 --- a/src/main/java/br/unicamp/meca/models/ActionStep.java +++ b/src/main/java/br/unicamp/meca/models/ActionStep.java @@ -24,6 +24,8 @@ public abstract class ActionStep { String actionId; Map parameters; + public boolean needsConclusion = false; + public boolean executed = false; public ActionStep() { actionId = ""; diff --git a/src/main/java/br/unicamp/meca/system1/codelets/ActivityCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/ActivityCodelet.java index f5b63fc..4c87b1e 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/ActivityCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/ActivityCodelet.java @@ -93,7 +93,8 @@ public void accessMemoryObjects() { for(String perceptualCodeletId : perceptualCodeletsIds) { Memory perceptualMemory = this.getInput(perceptualCodeletId, index); - perceptualMemories.add(perceptualMemory); + if (perceptualMemory != null) + perceptualMemories.add(perceptualMemory); } } } @@ -107,7 +108,8 @@ public void accessMemoryObjects() { for(String motivationalCodeletsId : motivationalCodeletsIds) { Memory inputDrive = this.getInput(motivationalCodeletsId + "Drive"); - driveMemories.add(inputDrive); + if (inputDrive != null) + driveMemories.add(inputDrive); } } } @@ -168,11 +170,20 @@ public void calculateActivation() { public void proc() { if(actionSequencePlanMemoryContainer != null && actionSequencePlanMemoryContainer.getI() != null && actionSequencePlanMemoryContainer.getI() instanceof ActionSequencePlan) { ActionSequencePlan actionSequencePlan = (ActionSequencePlan) actionSequencePlanMemoryContainer.getI(); - String currentActionId = actionSequencePlan.getCurrentActionStep().getActionId(); + ActionStep currentAction = actionSequencePlan.getCurrentActionStep(); + String currentActionId = currentAction.getActionId(); - if(currentActionId != null && currentActionId.equalsIgnoreCase(id)) { + if(currentActionId != null && currentActionId.equalsIgnoreCase(id) && currentAction.executed == false) { proc(perceptualMemories, broadcastMemory, motorMemory); } + else { + ActionStep lastActionStep = actionSequencePlan.getLastActionStep(); + String lastActionId = lastActionStep.getActionId(); + if (lastActionStep != null && lastActionStep.needsConclusion && lastActionId.equalsIgnoreCase(id)) { + doConclusion(perceptualMemories, broadcastMemory, motorMemory); + lastActionStep.needsConclusion = false; + } + } }else { proc(perceptualMemories, broadcastMemory, motorMemory); } @@ -189,6 +200,19 @@ public void proc() { * the output motor memory. */ public abstract void proc(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory); + + /** + * Method to be called to do the Conclusion of an ActionStep, after its activities are over. + * Similar to the proc method, but to be called one last time to clean whatever needs to be cleaned at the motorMemory + * + * @param perceptualMemories + * the input memories coming from perception. + * @param broadcastMemory + * the input memory coming from the conscious planner broadcast. + * @param motorMemory + * the output motor memory. + */ + public abstract void doConclusion(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory); /** * Returns the id of the Soar Codelet whose outputs will be read by this @@ -278,4 +302,24 @@ public void setMotorCodeletId(String motorCodeletId) { public ArrayList getMotivationalCodeletsIds() { return motivationalCodeletsIds; } + + public ArrayList getPerceptionMemories() { + return(perceptualMemories); + } + + public ArrayList getDriveMemories() { + return(driveMemories); + } + + public Memory getBroadcastMemory() { + return(broadcastMemory); + } + + public Memory getActionSequencePlanMemoryContainer() { + return(actionSequencePlanMemoryContainer); + } + + public Memory getMotorMemory() { + return(motorMemory); + } } diff --git a/src/main/java/br/unicamp/meca/system1/codelets/ActivityTrackingCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/ActivityTrackingCodelet.java index 62e4cbf..a722b78 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/ActivityTrackingCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/ActivityTrackingCodelet.java @@ -100,18 +100,22 @@ public void trackActionSequencePlan(ArrayList perceptualMemories, Action perceptualMemories != null && perceptualMemories.size() > 0) { ActionStep currentActionStep = actionSequencePlan.getCurrentActionStep(); - if (currentActionStep.stopCondition(perceptualMemories)) { - actionSequencePlan.gotoNextAction(); - } + ActionStep lastActionStep = actionSequencePlan.getLastActionStep(); + if (actionSequencePlan.getCurrentActionIdIndex() == 0 || lastActionStep.needsConclusion == false) { + if (currentActionStep != null && currentActionStep.executed == false && currentActionStep.stopCondition(perceptualMemories)) { + currentActionStep.needsConclusion = true; + actionSequencePlan.gotoNextAction(); + } + } } } @Override public void proc() { - - actionSequencePlan = (ActionSequencePlan) actionSequencePlanMemoryContainer.getI(); - - trackActionSequencePlan(perceptualMemories, actionSequencePlan); + if (actionSequencePlanMemoryContainer != null) { + actionSequencePlan = (ActionSequencePlan) actionSequencePlanMemoryContainer.getI(); + trackActionSequencePlan(perceptualMemories, actionSequencePlan); + } } /** diff --git a/src/test/java/br/unicamp/meca/mind/action/Test1ActivityCodelet.java b/src/test/java/br/unicamp/meca/mind/action/Test1ActivityCodelet.java index f61e0a2..3377e91 100644 --- a/src/test/java/br/unicamp/meca/mind/action/Test1ActivityCodelet.java +++ b/src/test/java/br/unicamp/meca/mind/action/Test1ActivityCodelet.java @@ -26,6 +26,12 @@ public Test1ActivityCodelet(String id, ArrayList perceptualCodeletsIds, ArrayList motivationalCodeletsIds, String motorCodeletId, String soarCodeletId) { super(id, perceptualCodeletsIds, motivationalCodeletsIds, motorCodeletId, soarCodeletId); } + + @Override + public void doConclusion(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory) { + System.out.println("Concluding Test1Activity"); + ((MemoryContainer) motorMemory).setI("Test1Activity - concluded",getActivation(),id); + } @Override public void proc(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory) { diff --git a/src/test/java/br/unicamp/meca/mind/action/Test2ActivityCodelet.java b/src/test/java/br/unicamp/meca/mind/action/Test2ActivityCodelet.java index 9d78e85..e0d8d26 100644 --- a/src/test/java/br/unicamp/meca/mind/action/Test2ActivityCodelet.java +++ b/src/test/java/br/unicamp/meca/mind/action/Test2ActivityCodelet.java @@ -26,6 +26,11 @@ public Test2ActivityCodelet(String id, ArrayList perceptualCodeletsIds, ArrayList motivationalCodeletsIds, String motorCodeletId, String soarCodeletId) { super(id, perceptualCodeletsIds, motivationalCodeletsIds, motorCodeletId, soarCodeletId); } + + @Override + public void doConclusion(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory) { + System.out.println("Concluding Test2Activity"); + } @Override public void proc(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory) { diff --git a/src/test/java/br/unicamp/meca/mind/action/Test3ActivityCodelet.java b/src/test/java/br/unicamp/meca/mind/action/Test3ActivityCodelet.java index 66d7524..8cd68fd 100644 --- a/src/test/java/br/unicamp/meca/mind/action/Test3ActivityCodelet.java +++ b/src/test/java/br/unicamp/meca/mind/action/Test3ActivityCodelet.java @@ -26,6 +26,11 @@ public Test3ActivityCodelet(String id, ArrayList perceptualCodeletsIds, ArrayList motivationalCodeletsIds, String motorCodeletId, String soarCodeletId) { super(id, perceptualCodeletsIds, motivationalCodeletsIds, motorCodeletId, soarCodeletId); } + + @Override + public void doConclusion(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory) { + System.out.println("Concluding Test3Activity"); + } @Override public void proc(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory) { diff --git a/src/test/java/br/unicamp/meca/mind/action/TestActivityCodelet.java b/src/test/java/br/unicamp/meca/mind/action/TestActivityCodelet.java new file mode 100644 index 0000000..51a724c --- /dev/null +++ b/src/test/java/br/unicamp/meca/mind/action/TestActivityCodelet.java @@ -0,0 +1,152 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package br.unicamp.meca.mind.action; + +import br.unicamp.cst.core.entities.MemoryContainer; +import br.unicamp.cst.core.entities.MemoryObject; +import br.unicamp.meca.mind.MecaMind; +import br.unicamp.meca.mind.motor.TestMotorCodelet; +import br.unicamp.meca.mind.perceptual.TestPerceptualCodelet; +import br.unicamp.meca.mind.sensory.TestPerceptionSensoryCodelet; +import br.unicamp.meca.models.ActionSequencePlan; +import br.unicamp.meca.models.ActionStep; +import br.unicamp.meca.models.ActionStepTest; +import br.unicamp.meca.system1.codelets.ActivityCodelet; +import br.unicamp.meca.system1.codelets.MotorCodelet; +import br.unicamp.meca.system1.codelets.PerceptualCodelet; +import br.unicamp.meca.system1.codelets.SensoryCodelet; +import java.util.ArrayList; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +/** + * + * @author rgudwin + */ +public class TestActivityCodelet { + + SensoryCodelet sc; + PerceptualCodelet pc; + ActivityCodelet ac; + + @Test + public void testAccessMemoryObjects() { + ArrayList lsc = new ArrayList(); + lsc.add("m1"); + lsc.add("m2"); + lsc.add("m3"); + ac = new Test1ActivityCodelet("teste",lsc,lsc,null,null); + ac.accessMemoryObjects(); + assertEquals(ac.getPerceptionMemories().size(),0); + MemoryObject mo = new MemoryObject(); + mo.setType("m1"); + ac.addInput(mo); + mo = new MemoryObject(); + mo.setType("m2"); + ac.addInput(mo); + mo = new MemoryObject(); + mo.setType("m3"); + ac.addInput(mo); + ac.accessMemoryObjects(); + assertEquals(ac.getPerceptionMemories().size(),3); + mo = new MemoryObject(); + mo.setType("m1Drive"); + ac.addInput(mo); + mo = new MemoryObject(); + mo.setType("m2Drive"); + ac.addInput(mo); + mo = new MemoryObject(); + mo.setType("m3Drive"); + ac.addInput(mo); + ac.accessMemoryObjects(); + assertEquals(ac.getDriveMemories().size(),3); + ac = new Test1ActivityCodelet("teste",null,null,"motor","soar"); + mo = new MemoryObject(); + mo.setType("motor"); + ac.addOutput(mo); + ac.accessMemoryObjects(); + assertEquals(ac.getMotorMemory(),mo); + mo = new MemoryObject(); + mo.setType("soar"); + ac.addBroadcast(mo); + ac.accessMemoryObjects(); + assertEquals(ac.getBroadcastMemory(),mo); + MemoryContainer mc = new MemoryContainer(); + mc.setType(MecaMind.ACTION_SEQUENCE_PLAN_ID); + ac.addInput(mc); + ac.accessMemoryObjects(); + assertEquals(ac.getActionSequencePlanMemoryContainer(),mc); + } + + @Test + public void testActivityCodelet() { + sc = new TestPerceptionSensoryCodelet("sensory"); + ArrayList lsc = new ArrayList(); + lsc.add("sensory"); + pc = new TestPerceptualCodelet("perception",lsc); + lsc = new ArrayList(); + ac = new Test1ActivityCodelet("teste",null,null,null,null); + ac.accessMemoryObjects(); + ac.proc(); + ac.calculateActivation(); + + ac = new Test1ActivityCodelet("teste",lsc,lsc,null,null); + ac.accessMemoryObjects(); + ac.proc(); + ac.calculateActivation(); + + ac = new Test1ActivityCodelet("teste",lsc,lsc,"motor",null); + ac.accessMemoryObjects(); + ac.proc(); + ac.calculateActivation(); + + MotorCodelet mc = new TestMotorCodelet("motor"); + ac.accessMemoryObjects(); + ac.proc(); + ac.calculateActivation(); + + } + + @Test + public void testCalculateActivation() { + ArrayList lsc = new ArrayList(); + lsc.add("m1"); + lsc.add("m2"); + lsc.add("m3"); + ac = new Test1ActivityCodelet("teste",null,lsc,null,null); + MemoryObject mo = new MemoryObject(); + mo.setType("m1Drive"); + mo.setEvaluation(0.5); + ac.addInput(mo); + mo = new MemoryObject(); + mo.setType("m2Drive"); + mo.setEvaluation(0.6); + ac.addInput(mo); + mo = new MemoryObject(); + mo.setType("m3Drive"); + ac.addInput(mo); + mo.setEvaluation(0.8); + ac.accessMemoryObjects(); + ac.calculateActivation(); + double presumedActivation = (0.5+0.6+0.8)/3; + assertEquals(ac.getActivation(),presumedActivation,0); + MemoryContainer mc = new MemoryContainer(); + mc.setType(MecaMind.ACTION_SEQUENCE_PLAN_ID); + ActionStep as[] = new ActionStep[1]; + ActionSequencePlan asp = new ActionSequencePlan(as); + mc.setI(asp,0.2); + ac.addInput(mc); + ac.accessMemoryObjects(); + ac.calculateActivation(); + // Because the ActionStep is null, the evaluation is 0 + assertEquals(ac.getActivation(),0,0); + as[0] = new ActionStepTest("teste"); + // Now that there is an action step with the same name as the ActivityCodelet, it should be 0.2 + ac.calculateActivation(); + assertEquals(ac.getActivation(),0.2,0); + } + +} diff --git a/src/test/java/br/unicamp/meca/mind/tracking/testActivityTrackingCodelet.java b/src/test/java/br/unicamp/meca/mind/tracking/testActivityTrackingCodelet.java new file mode 100644 index 0000000..e94791f --- /dev/null +++ b/src/test/java/br/unicamp/meca/mind/tracking/testActivityTrackingCodelet.java @@ -0,0 +1,115 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package br.unicamp.meca.mind.tracking; + +import br.unicamp.cst.core.entities.MemoryContainer; +import br.unicamp.cst.core.entities.MemoryObject; +import br.unicamp.meca.mind.MecaMind; +import br.unicamp.meca.models.ActionSequencePlan; +import br.unicamp.meca.models.ActionStep; +import br.unicamp.meca.models.ActionStepTest; +import br.unicamp.meca.system1.codelets.ActivityTrackingCodelet; +import java.util.ArrayList; +import java.util.List; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +/** + * + * @author rgudwin + */ +public class testActivityTrackingCodelet { + ActivityTrackingCodelet atc; + + @Test + public void testActivityTrackingCodelet() { + atc = new ActivityTrackingCodelet("tracking",null); + atc.accessMemoryObjects(); + atc.calculateActivation(); + // This tests the case when there is still no sequence plan to be tracked + atc.proc(); + // Now let's introduce an empty perception list + ArrayList lop = new ArrayList(); + atc = new ActivityTrackingCodelet("tracking",lop); + atc.accessMemoryObjects(); + atc.calculateActivation(); + atc.proc(); + // Now let's define an inexistent perception + lop.add("perception"); + atc.accessMemoryObjects(); + atc.calculateActivation(); + atc.proc(); + // Now, still without perception, let's introduce a sequence plan + MemoryContainer mc = new MemoryContainer(); + mc.setType(MecaMind.ACTION_SEQUENCE_PLAN_ID); + atc.addInput(mc); + atc.accessMemoryObjects(); + // Now there is a memory object, but still no sequence plan + atc.accessMemoryObjects(); + atc.calculateActivation(); + atc.proc(); + // Now let's include a plan, but still without any action step + ActionStep as[] = new ActionStep[3]; + ActionSequencePlan asp = new ActionSequencePlan(as); + mc.setI(asp,0.2); + atc.accessMemoryObjects(); + atc.calculateActivation(); + atc.proc(); + // Finally, let's include the action steps + ActionStep as1 = new ActionStepTest("tracking"); + as[0] = as1; + ActionStep as2 = new ActionStepTest("tracking"); + as[1] = as2; + ActionStep as3 = new ActionStepTest("tracking"); + as[2] = as3; + atc.accessMemoryObjects(); + atc.calculateActivation(); + atc.proc(); + assertEquals(asp.getCurrentActionIdIndex(),0); + // Now let's introduce a Perception Memory to track + // And now finally let's provide an existent perception, still without info + MemoryObject per = new MemoryObject(); + per.setType("perception"); + atc = new ActivityTrackingCodelet("tracking",lop); + atc.addInput(per); + atc.addInput(mc); + atc.accessMemoryObjects(); + atc.calculateActivation(); + atc.proc(); + assertEquals(asp.getCurrentActionIdIndex(),0); + // Now, let's create the conditions for the codelet decide to move to its 2nd step + per.setEvaluation(1.0); + atc.addInput(per); + //as[0].needsConclusion = true; + atc.accessMemoryObjects(); + atc.calculateActivation(); + assertEquals(as[0].executed,false); + atc.proc(); + // Now, because there are conditions for move to the second step of the plan, the index should be 1 + assertEquals(as[0].executed,true); + // Because the ActionStep 0 was executed, now it needs conclusion + assertEquals(as[0].needsConclusion,true); + assertEquals(asp.getCurrentActionIdIndex(),1); + assertEquals(as[1].executed,false); + atc.proc(); + // Now let's play a little ... because the conclusion didn't come, this proc will not move to the 3rd action step + assertEquals(as[1].executed,false); + // Let's then conclude the action step 0 e see what happens + as[0].needsConclusion = false; + atc.proc(); + // Now, this allows the execution of action step 1 + assertEquals(as[1].executed,true); + assertEquals(asp.getCurrentActionIdIndex(),2); + assertEquals(as[2].executed,false); + assertEquals(as[1].needsConclusion,true); + as[1].needsConclusion = false; + atc.proc(); + assertEquals(as[2].needsConclusion,true); + assertEquals(asp.getCurrentActionIdIndex(),0); + assertEquals(as[2].executed,true); + } + +} diff --git a/src/test/java/br/unicamp/meca/models/ActionSequencePlanTest.java b/src/test/java/br/unicamp/meca/models/ActionSequencePlanTest.java index 971d874..823b33f 100644 --- a/src/test/java/br/unicamp/meca/models/ActionSequencePlanTest.java +++ b/src/test/java/br/unicamp/meca/models/ActionSequencePlanTest.java @@ -12,22 +12,91 @@ * */ public class ActionSequencePlanTest { + + ActionStep as1 = new ActionStepTest("Land"); + ActionStep as2 = new ActionStepTest("Stop"); + ActionSequencePlan landAndStopSequencePlan = new ActionSequencePlan(new ActionStep[] {as1,as2}); public void setUp() { System.out.println("########## Action Sequence Plan TESTS ##########"); } + + @Test + public void testGetCurrentActionIdIndex() { + landAndStopSequencePlan.setCurrentActionIdIndex(0); + int currentStep = landAndStopSequencePlan.getCurrentActionIdIndex(); + assertEquals(currentStep,0); + landAndStopSequencePlan.setCurrentActionIdIndex(1); + currentStep = landAndStopSequencePlan.getCurrentActionIdIndex(); + assertEquals(currentStep,1); + } @Test public void testGetCurrentActionId() { - - ActionStep as1 = new ActionStepTest("Land"); - ActionStep as2 = new ActionStepTest("Stop"); - ActionSequencePlan landAndStopSequencePlan = new ActionSequencePlan(new ActionStep[] {as1,as2}); - + landAndStopSequencePlan.setCurrentActionIdIndex(0); assertEquals(landAndStopSequencePlan.getCurrentActionStep().getActionId(), "Land"); - + landAndStopSequencePlan.setCurrentActionIdIndex(1); - assertEquals(landAndStopSequencePlan.getCurrentActionStep().getActionId(), "Stop"); } + + @Test + public void testGetCurrentActionStep() { + landAndStopSequencePlan.setCurrentActionIdIndex(0); + ActionStep as = landAndStopSequencePlan.getCurrentActionStep(); + assertEquals(as,as1); + landAndStopSequencePlan.setCurrentActionIdIndex(1); + as = landAndStopSequencePlan.getCurrentActionStep(); + assertEquals(as,as2); + } + + @Test + public void testLastActionStep() { + landAndStopSequencePlan.setCurrentActionIdIndex(0); + ActionStep lastAS = landAndStopSequencePlan.getLastActionStep(); + assertEquals(lastAS,as2); + assertEquals(lastAS.executed,false); + assertEquals(lastAS.needsConclusion,false); + + landAndStopSequencePlan.setCurrentActionIdIndex(1); + lastAS = landAndStopSequencePlan.getLastActionStep(); + assertEquals(lastAS,as1); + assertEquals(lastAS.executed,false); + assertEquals(lastAS.needsConclusion,false); + } + + @Test + public void testGoToNextAction() { + landAndStopSequencePlan.setCurrentActionIdIndex(0); + ActionStep as = landAndStopSequencePlan.getCurrentActionStep(); + assertEquals(as,as1); + assertEquals(as1.executed,false); + + landAndStopSequencePlan.gotoNextAction(); + as = landAndStopSequencePlan.getCurrentActionStep(); + assertEquals(as,as2); + assertEquals(as1.executed,true); + assertEquals(as2.executed,false); + landAndStopSequencePlan.gotoNextAction(); + as = landAndStopSequencePlan.getCurrentActionStep(); + assertEquals(as,as1); + assertEquals(as2.executed,true); + } + + @Test + public void testResetPlan() { + as1.executed = true; + as2.executed = true; + landAndStopSequencePlan.resetPlan(); + for (ActionStep ass : landAndStopSequencePlan.getActionStepSequence()) { + assertEquals(ass.executed,false); + assertEquals(ass.needsConclusion,false); + } + } + + @Test + public void testToString() { + String s = landAndStopSequencePlan.toString(); + assertEquals(s,"{Land, Stop}"); + } } diff --git a/src/test/java/br/unicamp/meca/models/ActionStepTest.java b/src/test/java/br/unicamp/meca/models/ActionStepTest.java index d1b488b..488e3f1 100644 --- a/src/test/java/br/unicamp/meca/models/ActionStepTest.java +++ b/src/test/java/br/unicamp/meca/models/ActionStepTest.java @@ -25,6 +25,11 @@ public void setUp() { @Override public boolean stopCondition(List perceptions) { + if (perceptions != null && perceptions.size() > 0) { + Memory perceptionMemory = perceptions.get(0); + if (perceptionMemory != null && perceptionMemory.getEvaluation() > 0.5) return(true); + else return(false); + } return(false); } diff --git a/src/test/java/br/unicamp/meca/models/ActionStepTester.java b/src/test/java/br/unicamp/meca/models/ActionStepTester.java index 0e7fd0e..aae2313 100644 --- a/src/test/java/br/unicamp/meca/models/ActionStepTester.java +++ b/src/test/java/br/unicamp/meca/models/ActionStepTester.java @@ -4,8 +4,6 @@ * and open the template in the editor. */ package br.unicamp.meca.models; -import br.unicamp.cst.core.entities.Memory; -import java.util.List; import static org.junit.Assert.assertEquals; import org.junit.Test; From 1079a8cc3a50d749c4e70ddf911c2a62f9288395 Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Wed, 18 Nov 2020 12:54:05 -0300 Subject: [PATCH 33/89] New tests for doConclusion and other requested modifications --- .../meca/models/ActionSequencePlan.java | 12 +-- .../system1/codelets/ActivityCodelet.java | 2 +- .../codelets/ActivityTrackingCodelet.java | 14 ++-- .../mind/action/Test1ActivityCodelet.java | 8 +- .../mind/action/Test2ActivityCodelet.java | 2 +- .../mind/action/Test3ActivityCodelet.java | 2 +- .../tracking/testActivityTrackingCodelet.java | 78 ++++++++++++++++++- .../meca/models/ActionSequencePlanTest.java | 4 +- 8 files changed, 100 insertions(+), 22 deletions(-) diff --git a/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java b/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java index 2e183fc..483b97f 100644 --- a/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java +++ b/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java @@ -46,7 +46,7 @@ public ActionSequencePlan(ActionStep[] actionIdSequence) { /** * Returns the ActionStep of the current ActionFromPlanningCodelet to be undertaken in the plan. * - * @return currentActionId + * @return the current ActionStep */ public ActionStep getCurrentActionStep() { return actionIdSequence[currentActionIdIndex]; @@ -55,9 +55,9 @@ public ActionStep getCurrentActionStep() { /** * Returns the ActionStep of the last ActionFromPlanningCodelet to be undertaken in the plan, or null if it is the first step. * - * @return currentActionId + * @return the last ActionStep */ - public ActionStep getLastActionStep() { + public ActionStep getLastExecutedActionStep() { if (currentActionIdIndex == 0) return(actionIdSequence[actionIdSequence.length-1]); else return actionIdSequence[currentActionIdIndex-1]; } @@ -74,10 +74,10 @@ public ActionStep[] getActionStepSequence() { /** * Forces a new actionStepSequence * - * @param actionIdSequence the actionIdSequence to set + * @param actionStepSequence the actionIdSequence to set */ - public void setActionStepSequence(ActionStep[] actionIdSequence) { - this.actionIdSequence = actionIdSequence; + public void setActionStepSequence(ActionStep[] actionStepSequence) { + this.actionIdSequence = actionStepSequence; } /** diff --git a/src/main/java/br/unicamp/meca/system1/codelets/ActivityCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/ActivityCodelet.java index 4c87b1e..c365b7a 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/ActivityCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/ActivityCodelet.java @@ -177,7 +177,7 @@ public void proc() { proc(perceptualMemories, broadcastMemory, motorMemory); } else { - ActionStep lastActionStep = actionSequencePlan.getLastActionStep(); + ActionStep lastActionStep = actionSequencePlan.getLastExecutedActionStep(); String lastActionId = lastActionStep.getActionId(); if (lastActionStep != null && lastActionStep.needsConclusion && lastActionId.equalsIgnoreCase(id)) { doConclusion(perceptualMemories, broadcastMemory, motorMemory); diff --git a/src/main/java/br/unicamp/meca/system1/codelets/ActivityTrackingCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/ActivityTrackingCodelet.java index a722b78..d3a3858 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/ActivityTrackingCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/ActivityTrackingCodelet.java @@ -100,12 +100,14 @@ public void trackActionSequencePlan(ArrayList perceptualMemories, Action perceptualMemories != null && perceptualMemories.size() > 0) { ActionStep currentActionStep = actionSequencePlan.getCurrentActionStep(); - ActionStep lastActionStep = actionSequencePlan.getLastActionStep(); - if (actionSequencePlan.getCurrentActionIdIndex() == 0 || lastActionStep.needsConclusion == false) { - if (currentActionStep != null && currentActionStep.executed == false && currentActionStep.stopCondition(perceptualMemories)) { - currentActionStep.needsConclusion = true; - actionSequencePlan.gotoNextAction(); - } + ActionStep lastActionStep = actionSequencePlan.getLastExecutedActionStep(); + if ((actionSequencePlan.getCurrentActionIdIndex() == 0 + || lastActionStep.needsConclusion == false) // you can go to next step if it is the first step of the plan or if the last step is clear + && (currentActionStep != null // then just check if current ActionStep is not null to avoid breaking the next tests + && currentActionStep.executed == false // the ActionStep was not already executed + && currentActionStep.stopCondition(perceptualMemories)) ) { // and the ActionStep reached its final destination + currentActionStep.needsConclusion = true; + actionSequencePlan.gotoNextAction(); } } } diff --git a/src/test/java/br/unicamp/meca/mind/action/Test1ActivityCodelet.java b/src/test/java/br/unicamp/meca/mind/action/Test1ActivityCodelet.java index 3377e91..89b2d77 100644 --- a/src/test/java/br/unicamp/meca/mind/action/Test1ActivityCodelet.java +++ b/src/test/java/br/unicamp/meca/mind/action/Test1ActivityCodelet.java @@ -29,8 +29,8 @@ public Test1ActivityCodelet(String id, ArrayList perceptualCodeletsIds, @Override public void doConclusion(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory) { - System.out.println("Concluding Test1Activity"); - ((MemoryContainer) motorMemory).setI("Test1Activity - concluded",getActivation(),id); + System.out.println("Concluding "+id); + ((MemoryContainer) motorMemory).setI(id+" - concluded",getActivation(),id); } @Override @@ -39,13 +39,13 @@ public void proc(ArrayList perceptualMemories, Memory broadcastMemory, M return; } - motorMemory.setI(null); + ((MemoryContainer) motorMemory).setI(null,0.0,id); for(Memory memory: perceptualMemories) { if(memory.getI()!=null && memory.getI() instanceof String) { String perceptualContent = (String) memory.getI(); - ((MemoryContainer) motorMemory).setI("Test1Activity - "+perceptualContent,getActivation(),id); + ((MemoryContainer) motorMemory).setI(id+" - "+perceptualContent,getActivation(),id); } } } diff --git a/src/test/java/br/unicamp/meca/mind/action/Test2ActivityCodelet.java b/src/test/java/br/unicamp/meca/mind/action/Test2ActivityCodelet.java index e0d8d26..22ad0bc 100644 --- a/src/test/java/br/unicamp/meca/mind/action/Test2ActivityCodelet.java +++ b/src/test/java/br/unicamp/meca/mind/action/Test2ActivityCodelet.java @@ -38,7 +38,7 @@ public void proc(ArrayList perceptualMemories, Memory broadcastMemory, M return; } - motorMemory.setI(null); + ((MemoryContainer) motorMemory).setI(null,0.0,id); for(Memory memory: perceptualMemories) { if(memory.getI()!=null && memory.getI() instanceof String) { diff --git a/src/test/java/br/unicamp/meca/mind/action/Test3ActivityCodelet.java b/src/test/java/br/unicamp/meca/mind/action/Test3ActivityCodelet.java index 8cd68fd..01ba847 100644 --- a/src/test/java/br/unicamp/meca/mind/action/Test3ActivityCodelet.java +++ b/src/test/java/br/unicamp/meca/mind/action/Test3ActivityCodelet.java @@ -38,7 +38,7 @@ public void proc(ArrayList perceptualMemories, Memory broadcastMemory, M return; } - motorMemory.setI(null); + ((MemoryContainer) motorMemory).setI(null,0.0,id); for(Memory memory: perceptualMemories) { if(memory.getI()!=null && memory.getI() instanceof String) { diff --git a/src/test/java/br/unicamp/meca/mind/tracking/testActivityTrackingCodelet.java b/src/test/java/br/unicamp/meca/mind/tracking/testActivityTrackingCodelet.java index e94791f..ae20e31 100644 --- a/src/test/java/br/unicamp/meca/mind/tracking/testActivityTrackingCodelet.java +++ b/src/test/java/br/unicamp/meca/mind/tracking/testActivityTrackingCodelet.java @@ -8,12 +8,13 @@ import br.unicamp.cst.core.entities.MemoryContainer; import br.unicamp.cst.core.entities.MemoryObject; import br.unicamp.meca.mind.MecaMind; +import br.unicamp.meca.mind.action.Test1ActivityCodelet; import br.unicamp.meca.models.ActionSequencePlan; import br.unicamp.meca.models.ActionStep; import br.unicamp.meca.models.ActionStepTest; +import br.unicamp.meca.system1.codelets.ActivityCodelet; import br.unicamp.meca.system1.codelets.ActivityTrackingCodelet; import java.util.ArrayList; -import java.util.List; import static org.junit.Assert.assertEquals; import org.junit.Test; @@ -23,6 +24,8 @@ */ public class testActivityTrackingCodelet { ActivityTrackingCodelet atc; + ActivityCodelet actc1; + ActivityCodelet actc2; @Test public void testActivityTrackingCodelet() { @@ -112,4 +115,77 @@ public void testActivityTrackingCodelet() { assertEquals(as[2].executed,true); } + @Test + public void testDoConclusion() { + // Creation of the Perception Memory + ArrayList lop = new ArrayList(); + MemoryObject per = new MemoryObject(); + per.setType("perception"); + per.setI("perception"); + lop.add("perception"); + atc = new ActivityTrackingCodelet("tracking",lop); + atc.addInput(per); + // Creation of the ActionSequencePlan + MemoryContainer planContainer = new MemoryContainer(); + planContainer.setType(MecaMind.ACTION_SEQUENCE_PLAN_ID); + ActionStep as1 = new ActionStepTest("activity1"); + ActionStep as2 = new ActionStepTest("activity2"); + ActionSequencePlan asp = new ActionSequencePlan(new ActionStep[] {as1,as2}); + planContainer.setI(asp,0.2,"plan"); + atc.addInput(planContainer); + // Creation of the MotorMemory + MemoryContainer motorMemory = new MemoryContainer(); + motorMemory.setType("motor"); + // Now creating the ActivityCodelets which will serve the ActionStep + actc1 = new Test1ActivityCodelet("activity1",lop,null,"motor",null); + actc1.addInput(per); + actc1.addInput(planContainer); + actc1.addOutput(motorMemory); + actc2 = new Test1ActivityCodelet("activity2",lop,null,"motor",null); + actc2.addInput(per); + actc2.addInput(planContainer); + actc2.addOutput(motorMemory); + // Execute the 1st time step + step(); + // Verifying if the activity1 modified the motor codelet + assertEquals(motorMemory.getI(),"activity1 - perception"); + // now let's cause the ActivityTrackingCodelet to conclude step 1 and move to step 2 + per.setEvaluation(1.0); + // And change the activation to a lower value than activity1 ... + // if activity1 is not concluded by doConclusion, it will stay at the motor codelet and ruin the output of motorCodelet + planContainer.setI(asp,0.1,"plan"); + step(); + // Let's first verify if the plan was advanced to step 2 + assertEquals(asp.getCurrentActionIdIndex(),1); + // Let's verify if activity2 modified the motor codelet + assertEquals(motorMemory.getI(),"activity2 - perception"); + // Let's verify if activity1 was concluded + assertEquals(motorMemory.getI(0),"activity1 - concluded"); + // Now let's do one more step to conclude the plan + step(); + // And verify the plan is back to step 1 and executed + assertEquals(asp.getCurrentActionIdIndex(),0); + assertEquals(asp.getCurrentActionStep().executed,true); + assertEquals(asp.getLastExecutedActionStep().executed,true); + // Let's do a final step and check if everything remains the same + step(); + assertEquals(asp.getCurrentActionIdIndex(),0); + assertEquals(asp.getCurrentActionStep().executed,true); + assertEquals(asp.getLastExecutedActionStep().executed,true); + + } + + private void step() { + atc.accessMemoryObjects(); + atc.calculateActivation(); + atc.proc(); + actc1.accessMemoryObjects(); + actc1.calculateActivation(); + actc1.proc(); + actc2.accessMemoryObjects(); + actc2.calculateActivation(); + actc2.proc(); + } + + } diff --git a/src/test/java/br/unicamp/meca/models/ActionSequencePlanTest.java b/src/test/java/br/unicamp/meca/models/ActionSequencePlanTest.java index 823b33f..63c876e 100644 --- a/src/test/java/br/unicamp/meca/models/ActionSequencePlanTest.java +++ b/src/test/java/br/unicamp/meca/models/ActionSequencePlanTest.java @@ -53,13 +53,13 @@ public void testGetCurrentActionStep() { @Test public void testLastActionStep() { landAndStopSequencePlan.setCurrentActionIdIndex(0); - ActionStep lastAS = landAndStopSequencePlan.getLastActionStep(); + ActionStep lastAS = landAndStopSequencePlan.getLastExecutedActionStep(); assertEquals(lastAS,as2); assertEquals(lastAS.executed,false); assertEquals(lastAS.needsConclusion,false); landAndStopSequencePlan.setCurrentActionIdIndex(1); - lastAS = landAndStopSequencePlan.getLastActionStep(); + lastAS = landAndStopSequencePlan.getLastExecutedActionStep(); assertEquals(lastAS,as1); assertEquals(lastAS.executed,false); assertEquals(lastAS.needsConclusion,false); From 0b2123e8e7fd294376d1d4f9dfb1bd1a8fde38ae Mon Sep 17 00:00:00 2001 From: Andre Paraense Date: Wed, 18 Nov 2020 18:27:14 +0000 Subject: [PATCH 34/89] Bumping version in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 813e9d5..7bfe629 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ Sometimes, the version number (tag) in this README gets out of date, as maintain com.github.CST-Group meca - 0.4.2 + 0.4.3 ``` From faf2042a236225b028c1b1cec586da824257d94d Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Thu, 19 Nov 2020 12:41:13 -0300 Subject: [PATCH 35/89] Changes to ActivityCodelet to treat the case when two successive ActionSteps of the same type appear in the plan --- .../system1/codelets/ActivityCodelet.java | 24 ++++--- .../tracking/testActivityTrackingCodelet.java | 70 ++++++++++++++++++- 2 files changed, 83 insertions(+), 11 deletions(-) diff --git a/src/main/java/br/unicamp/meca/system1/codelets/ActivityCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/ActivityCodelet.java index c365b7a..e22565c 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/ActivityCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/ActivityCodelet.java @@ -168,23 +168,27 @@ public void calculateActivation() { @Override public void proc() { + // This is the case when this ActivityCodelet is following a plan - there is a plan available if(actionSequencePlanMemoryContainer != null && actionSequencePlanMemoryContainer.getI() != null && actionSequencePlanMemoryContainer.getI() instanceof ActionSequencePlan) { ActionSequencePlan actionSequencePlan = (ActionSequencePlan) actionSequencePlanMemoryContainer.getI(); ActionStep currentAction = actionSequencePlan.getCurrentActionStep(); - String currentActionId = currentAction.getActionId(); - - if(currentActionId != null && currentActionId.equalsIgnoreCase(id) && currentAction.executed == false) { - proc(perceptualMemories, broadcastMemory, motorMemory); - } - else { - ActionStep lastActionStep = actionSequencePlan.getLastExecutedActionStep(); - String lastActionId = lastActionStep.getActionId(); - if (lastActionStep != null && lastActionStep.needsConclusion && lastActionId.equalsIgnoreCase(id)) { + ActionStep lastActionStep = actionSequencePlan.getLastExecutedActionStep(); + String lastActionId; + if (lastActionStep != null) { + lastActionId = lastActionStep.getActionId(); + if (lastActionId != null && lastActionId.equalsIgnoreCase(id) && lastActionStep.needsConclusion) { doConclusion(perceptualMemories, broadcastMemory, motorMemory); lastActionStep.needsConclusion = false; } } - }else { + String currentActionId; + if (currentAction != null) { + currentActionId = currentAction.getActionId(); + if(currentActionId != null && currentActionId.equalsIgnoreCase(id) && currentAction.executed == false) { + proc(perceptualMemories, broadcastMemory, motorMemory); + } + } + }else { // This is the case when there is NO plan available, and the ActivityCodelet should be run only with Perception proc(perceptualMemories, broadcastMemory, motorMemory); } } diff --git a/src/test/java/br/unicamp/meca/mind/tracking/testActivityTrackingCodelet.java b/src/test/java/br/unicamp/meca/mind/tracking/testActivityTrackingCodelet.java index ae20e31..135cb4f 100644 --- a/src/test/java/br/unicamp/meca/mind/tracking/testActivityTrackingCodelet.java +++ b/src/test/java/br/unicamp/meca/mind/tracking/testActivityTrackingCodelet.java @@ -175,6 +175,65 @@ public void testDoConclusion() { } + @Test + public void testTwoActionStepsOfSameType() { + // Creation of the Perception Memory + ArrayList lop = new ArrayList(); + MemoryObject per = new MemoryObject(); + per.setType("perception"); + per.setI("perception"); + lop.add("perception"); + atc = new ActivityTrackingCodelet("tracking",lop); + atc.addInput(per); + // Creation of the ActionSequencePlan + MemoryContainer planContainer = new MemoryContainer(); + planContainer.setType(MecaMind.ACTION_SEQUENCE_PLAN_ID); + ActionStep as1 = new ActionStepTest("activity1"); + ActionStep as2 = new ActionStepTest("activity1"); // The 2nd actionstep is treated by the same ActivityCodelet + ActionSequencePlan asp = new ActionSequencePlan(new ActionStep[] {as1,as2}); + planContainer.setI(asp,0.2,"plan"); + atc.addInput(planContainer); + // Creation of the MotorMemory + MemoryContainer motorMemory = new MemoryContainer(); + motorMemory.setType("motor"); + // Now creating the ActivityCodelet which will serve the ActionStep + actc1 = new Test1ActivityCodelet("activity1",lop,null,"motor",null); + actc1.addInput(per); + actc1.addInput(planContainer); + actc1.addOutput(motorMemory); + // Execute the 1st time step + step2(); + // Verifying if the activity1 modified the motor codelet + assertEquals(motorMemory.getI(),"activity1 - perception"); + // now let's cause the ActivityTrackingCodelet to conclude step 1 and move to step 2 + per.setEvaluation(1.0); + // And change the activation to a lower value than activity1 ... + // if activity1 is not concluded by doConclusion, it will stay at the motor codelet and ruin the output of motorCodelet + planContainer.setI(asp,0.1,"plan"); + step2(); + // Let's first verify if the plan was advanced to step 2 + assertEquals(asp.getCurrentActionIdIndex(),1); + // The conclusion of step1 can only be verified by the log, as the motorMemory is immediately rewritten by step2 + // A "Concluding activity1" message should have appeared in the log + // But we can still check the needsConclusion flag, which should be cleared + assertEquals(asp.getLastExecutedActionStep().needsConclusion,false); + // Now let's do one more step to conclude the plan + step2(); + // And verify the plan is back to step 1 and executed + assertEquals(asp.getCurrentActionIdIndex(),0); + assertEquals(asp.getCurrentActionStep().needsConclusion,false); + assertEquals(asp.getCurrentActionStep().executed,true); + assertEquals(asp.getLastExecutedActionStep().needsConclusion,false); + assertEquals(asp.getLastExecutedActionStep().executed,true); + // Let's do a final step and check if everything remains the same + step2(); + assertEquals(asp.getCurrentActionIdIndex(),0); + assertEquals(asp.getCurrentActionStep().needsConclusion,false); + assertEquals(asp.getCurrentActionStep().executed,true); + assertEquals(asp.getLastExecutedActionStep().needsConclusion,false); + assertEquals(asp.getLastExecutedActionStep().executed,true); + } + private void step() { atc.accessMemoryObjects(); atc.calculateActivation(); @@ -186,6 +245,15 @@ private void step() { actc2.calculateActivation(); actc2.proc(); } - + + + private void step2() { + atc.accessMemoryObjects(); + atc.calculateActivation(); + atc.proc(); + actc1.accessMemoryObjects(); + actc1.calculateActivation(); + actc1.proc(); + } } From 794c0d7d0f0a52efd4e835c5a00e529a8e759343 Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Thu, 19 Nov 2020 12:45:28 -0300 Subject: [PATCH 36/89] Change version to 0.4.4 --- README.md | 4 ++-- build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 813e9d5..483fc10 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Note: This library is still under development, and some concepts or features mig ``` dependencies { ... - implementation 'com.github.CST-Group:meca:0.4.3' + implementation 'com.github.CST-Group:meca:0.4.4' } ``` @@ -53,7 +53,7 @@ Sometimes, the version number (tag) in this README gets out of date, as maintain com.github.CST-Group meca - 0.4.2 + 0.4.4 ``` diff --git a/build.gradle b/build.gradle index 17cfc0c..f3941ee 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ description = "The Multipurpose Enhanced Cognitive Architecture (MECA)" sourceCompatibility = 1.8 targetCompatibility = 1.8 -version = '0.4.3' +version = '0.4.4' repositories { mavenCentral() From 45b33010547fedbed5508ac4828aa81d2684587f Mon Sep 17 00:00:00 2001 From: Andre Paraense Date: Tue, 22 Dec 2020 16:05:31 -0300 Subject: [PATCH 37/89] Generalizing the SoarCodelet as a PlanningCodelet --- README.md | 4 +- build.gradle | 2 +- .../java/br/unicamp/meca/mind/MecaMind.java | 47 ++++++++-------- .../system1/codelets/ActivityCodelet.java | 30 +++++------ .../system1/codelets/BehaviorCodelet.java | 30 +++++------ .../system2/codelets/IPlanningCodelet.java | 53 +++++++++++++++++++ .../meca/system2/codelets/SoarCodelet.java | 2 +- 7 files changed, 112 insertions(+), 56 deletions(-) create mode 100644 src/main/java/br/unicamp/meca/system2/codelets/IPlanningCodelet.java diff --git a/README.md b/README.md index 483fc10..d15ec2d 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Note: This library is still under development, and some concepts or features mig ``` dependencies { ... - implementation 'com.github.CST-Group:meca:0.4.4' + implementation 'com.github.CST-Group:meca:0.5.0' } ``` @@ -53,7 +53,7 @@ Sometimes, the version number (tag) in this README gets out of date, as maintain com.github.CST-Group meca - 0.4.4 + 0.5.0 ``` diff --git a/build.gradle b/build.gradle index f3941ee..7bd9493 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ description = "The Multipurpose Enhanced Cognitive Architecture (MECA)" sourceCompatibility = 1.8 targetCompatibility = 1.8 -version = '0.4.4' +version = '0.5.0' repositories { mavenCentral() diff --git a/src/main/java/br/unicamp/meca/mind/MecaMind.java b/src/main/java/br/unicamp/meca/mind/MecaMind.java index ae7f88a..3954041 100644 --- a/src/main/java/br/unicamp/meca/mind/MecaMind.java +++ b/src/main/java/br/unicamp/meca/mind/MecaMind.java @@ -14,6 +14,7 @@ import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.UUID; @@ -41,8 +42,8 @@ import br.unicamp.meca.system2.codelets.EpisodicRetrievalCodelet; import br.unicamp.meca.system2.codelets.ExpectationCodelet; import br.unicamp.meca.system2.codelets.GoalCodelet; +import br.unicamp.meca.system2.codelets.IPlanningCodelet; import br.unicamp.meca.system2.codelets.SoarCodelet; -import java.util.Iterator; /** * This class represents the MECA's agent mind.This is the main class to be used @@ -74,7 +75,7 @@ public class MecaMind extends Mind { private Memory actionSequencePlanMemoryContainer; private Memory actionSequencePlanRequestMemoryContainer; private ActivityTrackingCodelet activityTrackingCodelet; - private static HashMap memoryGroups = new HashMap(); + private static HashMap memoryGroups = new HashMap(); /* * System 2 @@ -85,7 +86,7 @@ public class MecaMind extends Mind { private EpisodicRetrievalCodelet episodicRetrievalCodelet; private ExpectationCodelet expectationCodelet; private ConsciousnessCodelet consciousnessCodelet; - private SoarCodelet soarCodelet; + private IPlanningCodelet planningCodelet; private GoalCodelet goalCodelet; private AppraisalCodelet appraisalCodelet; private WorkingMemory workingMemory; @@ -150,7 +151,7 @@ public void mountMecaMind() { mountMotorCodelets(); mountAttentionCodelets(); mountWorkingMemory(); - mountSoarCodelet(); + mountPlanningCodelet(); mountMotivationalCodelets(); mountActionSequencePlanMemory(); mountBehaviorCodelets(); @@ -176,8 +177,8 @@ private void mountMemoryGroups() { } private void mountModules() { - if (getSoarCodelet() != null) { - getPlansSubsystemModule().setjSoarCodelet(getSoarCodelet()); + if (getPlanningCodelet() != null && getPlanningCodelet() instanceof SoarCodelet) { + getPlansSubsystemModule().setjSoarCodelet((SoarCodelet) getPlanningCodelet()); } } @@ -353,9 +354,9 @@ private void mountBehaviorCodelets() { } } } - if (soarCodelet != null && soarCodelet.getId() != null && behaviorCodelet.getSoarCodeletId() != null) { - if (soarCodelet.getId().equalsIgnoreCase(behaviorCodelet.getSoarCodeletId())) { - behaviorCodelet.addBroadcasts(soarCodelet.getOutputs()); + if (planningCodelet != null && planningCodelet.getId() != null && behaviorCodelet.getPlanningCodeletId() != null) { + if (planningCodelet.getId().equalsIgnoreCase(behaviorCodelet.getPlanningCodeletId())) { + behaviorCodelet.addBroadcasts(planningCodelet.getOutputs()); } } insertCodelet(behaviorCodelet); @@ -415,9 +416,9 @@ private void mountActivityCodelets() { } } } - if (soarCodelet != null && soarCodelet.getId() != null && activityCodelet.getSoarCodeletId() != null) { - if (soarCodelet.getId().equalsIgnoreCase(activityCodelet.getSoarCodeletId())) { - activityCodelet.addBroadcasts(soarCodelet.getOutputs()); + if (planningCodelet != null && planningCodelet.getId() != null && activityCodelet.getPlanningCodeletId() != null) { + if (planningCodelet.getId().equalsIgnoreCase(activityCodelet.getPlanningCodeletId())) { + activityCodelet.addBroadcasts(planningCodelet.getOutputs()); } } activityCodelet.addInput(actionSequencePlanMemoryContainer); @@ -465,11 +466,11 @@ private void mountAttentionCodelets() { } } - private void mountSoarCodelet() { - if (soarCodelet != null) { - soarCodelet.addInput(createMemoryObject(WorkingMemory.WORKING_MEMORY_INPUT, getWorkingMemory())); - soarCodelet.addOutput(createMemoryObject(soarCodelet.getId())); - insertCodelet(soarCodelet); + private void mountPlanningCodelet() { + if (planningCodelet != null) { + planningCodelet.addInput(createMemoryObject(WorkingMemory.WORKING_MEMORY_INPUT, getWorkingMemory())); + planningCodelet.addOutput(createMemoryObject(planningCodelet.getId())); + insertCodelet((Codelet) planningCodelet); } } @@ -612,11 +613,13 @@ public void setConsciousnessCodelet(ConsciousnessCodelet consciousnessCodelet) { /** * Sets the Soar Codelet. * + * @deprecated instead, add the SoarCodelet using the interface IPlanningCodelet * @param soarCodelet * the soarCodelet to set */ + @Deprecated public void setSoarCodelet(SoarCodelet soarCodelet) { - this.soarCodelet = soarCodelet; + this.planningCodelet = soarCodelet; } /** @@ -825,12 +828,12 @@ public ConsciousnessCodelet getConsciousnessCodelet() { } /** - * Gets the Soar Codelet. + * Gets the Planning Codelet. * - * @return the soarCodelet. + * @return the planningCodelet. */ - public SoarCodelet getSoarCodelet() { - return soarCodelet; + public IPlanningCodelet getPlanningCodelet() { + return planningCodelet; } /** diff --git a/src/main/java/br/unicamp/meca/system1/codelets/ActivityCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/ActivityCodelet.java index e22565c..05570fe 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/ActivityCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/ActivityCodelet.java @@ -39,7 +39,7 @@ public abstract class ActivityCodelet extends Codelet { protected ArrayList motivationalCodeletsIds; protected ArrayList driveMemories; - protected String soarCodeletId; + protected String planningCodeletId; protected Memory broadcastMemory; protected Memory actionSequencePlanMemoryContainer; @@ -63,8 +63,8 @@ public abstract class ActivityCodelet extends Codelet { * @param motorCodeletId * the id of the Motor Codelet which will read the outputs of * this Activity Codelet. - * @param soarCodeletId - * the id of the Soar Codelet whose outputs will be read by this + * @param planningCodeletId + * the id of the Planning Codelet whose outputs will be read by this * Activity Codelet. */ public ActivityCodelet( @@ -72,12 +72,12 @@ public ActivityCodelet( ArrayList perceptualCodeletsIds, ArrayList motivationalCodeletsIds, String motorCodeletId, - String soarCodeletId) { + String planningCodeletId) { setName(id); this.id = id; this.motorCodeletId = motorCodeletId; this.perceptualCodeletsIds = perceptualCodeletsIds; - this.soarCodeletId = soarCodeletId; + this.planningCodeletId = planningCodeletId; this.motivationalCodeletsIds = motivationalCodeletsIds; } @@ -115,7 +115,7 @@ public void accessMemoryObjects() { } if(broadcastMemory == null) { - broadcastMemory = this.getBroadcast(soarCodeletId, index); + broadcastMemory = this.getBroadcast(planningCodeletId, index); } @@ -219,24 +219,24 @@ public void proc() { public abstract void doConclusion(ArrayList perceptualMemories, Memory broadcastMemory, Memory motorMemory); /** - * Returns the id of the Soar Codelet whose outputs will be read by this + * Returns the id of the Planning Codelet whose outputs will be read by this * Activity Codelet. * - * @return the soarCodeletId + * @return the planningCodeletId */ - public String getSoarCodeletId() { - return soarCodeletId; + public String getPlanningCodeletId() { + return planningCodeletId; } /** - * Sets the id of the Soar Codelet whose outputs will be read by this + * Sets the id of the Planning Codelet whose outputs will be read by this * Activity Codelet. * - * @param soarCodeletId - * the soarCodeletId to set + * @param planningCodeletId + * the planningCodeletId to set */ - public void setSoarCodeletId(String soarCodeletId) { - this.soarCodeletId = soarCodeletId; + public void setPlanningCodeletId(String planningCodeletId) { + this.planningCodeletId = planningCodeletId; } /** diff --git a/src/main/java/br/unicamp/meca/system1/codelets/BehaviorCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/BehaviorCodelet.java index 928dd76..b7b9b9b 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/BehaviorCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/BehaviorCodelet.java @@ -46,7 +46,7 @@ public abstract class BehaviorCodelet extends Codelet { protected ArrayList motivationalCodeletsIds; protected ArrayList driveMemories; - protected String soarCodeletId; + protected String planningCodeletId; protected Memory broadcastMemory; protected ActionSequencePlan actionSequencePlan; @@ -67,19 +67,19 @@ public abstract class BehaviorCodelet extends Codelet { * @param motivationalCodeletsIds * the list of ids of the Motivational Codelets whose outputs * will be read by this Behavior Codelet. - * @param soarCodeletId - * the id of the Soar Codelet whose outputs will be read by this + * @param planningCodeletId + * the id of the Planning Codelet whose outputs will be read by this * Behavior Codelet. * @see Codelet */ public BehaviorCodelet(String id, ArrayList perceptualCodeletsIds, ArrayList motivationalCodeletsIds, - String soarCodeletId) { + String planningCodeletId) { super(); setName(id); this.id = id; this.perceptualCodeletsIds = perceptualCodeletsIds; this.motivationalCodeletsIds = motivationalCodeletsIds; - this.soarCodeletId = soarCodeletId; + this.planningCodeletId = planningCodeletId; } @Override @@ -115,7 +115,7 @@ public void accessMemoryObjects() { } if(broadcastMemory == null) { - broadcastMemory = this.getBroadcast(soarCodeletId, index); + broadcastMemory = this.getBroadcast(planningCodeletId, index); } if(actionSequencePlanMemoryContainer == null) @@ -184,24 +184,24 @@ public void proc() { /** - * Returns the id of the Soar Codelet whose outputs will be read by this + * Returns the id of the Planning Codelet whose outputs will be read by this * Behavior Codelet. * - * @return the soarCodeletId + * @return the planningCodeletId */ - public String getSoarCodeletId() { - return soarCodeletId; + public String getPlanningCodeletId() { + return planningCodeletId; } /** - * Sets the id of the Soar Codelet whose outputs will be read by this + * Sets the id of the Planning Codelet whose outputs will be read by this * Behavior Codelet. * - * @param soarCodeletId - * the soarCodeletId to set + * @param planningCodeletId + * the planningCodeletId to set */ - public void setSoarCodeletId(String soarCodeletId) { - this.soarCodeletId = soarCodeletId; + public void setPlanningCodeletId(String planningCodeletId) { + this.planningCodeletId = planningCodeletId; } /** diff --git a/src/main/java/br/unicamp/meca/system2/codelets/IPlanningCodelet.java b/src/main/java/br/unicamp/meca/system2/codelets/IPlanningCodelet.java new file mode 100644 index 0000000..1931e3a --- /dev/null +++ b/src/main/java/br/unicamp/meca/system2/codelets/IPlanningCodelet.java @@ -0,0 +1,53 @@ +/** + * + */ +package br.unicamp.meca.system2.codelets; + +import java.util.List; + +import br.unicamp.cst.core.entities.Memory; + +/** + * @author andre + * + */ +public interface IPlanningCodelet { + + /** + * Returns the id of this Planning Codelet. + * + * @return the id + */ + String getId(); + + /** + * Gets the list of output memories. + * + * @return the outputs. + */ + List getOutputs(); + + /** + * Add a memory to the output list. + * + * @param memory + * one output to set. + */ + void addOutput(Memory memory); + + /** + * Gets the input memories list. + * + * @return the inputs. + */ + List getInputs(); + + /** + * Add one memory to the input list. + * + * @param memory + * one input to set. + */ + void addInput(Memory memory); + +} diff --git a/src/main/java/br/unicamp/meca/system2/codelets/SoarCodelet.java b/src/main/java/br/unicamp/meca/system2/codelets/SoarCodelet.java index 4dd8dd1..73ce799 100644 --- a/src/main/java/br/unicamp/meca/system2/codelets/SoarCodelet.java +++ b/src/main/java/br/unicamp/meca/system2/codelets/SoarCodelet.java @@ -32,7 +32,7 @@ * @author W. Gibaut * @see br.unicamp.cst.bindings.soar.JSoarCodelet */ -public abstract class SoarCodelet extends br.unicamp.cst.bindings.soar.JSoarCodelet { +public abstract class SoarCodelet extends br.unicamp.cst.bindings.soar.JSoarCodelet implements IPlanningCodelet { private String id; From 8a933b4dff1e238701bb1c74a4d4b5efbe4f2088 Mon Sep 17 00:00:00 2001 From: Andre Paraense Date: Tue, 22 Dec 2020 17:09:25 -0300 Subject: [PATCH 38/89] Add planning codelet in tests --- .../java/br/unicamp/meca/mind/MecaMind.java | 7 +++ .../br/unicamp/meca/mind/MecaMindTest.java | 7 +++ .../meca/mind/planning/TestSoarCodelet.java | 49 +++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 src/test/java/br/unicamp/meca/mind/planning/TestSoarCodelet.java diff --git a/src/main/java/br/unicamp/meca/mind/MecaMind.java b/src/main/java/br/unicamp/meca/mind/MecaMind.java index 3954041..967d6c2 100644 --- a/src/main/java/br/unicamp/meca/mind/MecaMind.java +++ b/src/main/java/br/unicamp/meca/mind/MecaMind.java @@ -874,4 +874,11 @@ public void pregisterMemory(String memoryName, String memoryGroup) { public void setActivityCodelets(List activityCodelets) { this.activityCodelets = activityCodelets; } + + /** + * @param planningCodelet the planningCodelet to set + */ + public void setPlanningCodelet(IPlanningCodelet planningCodelet) { + this.planningCodelet = planningCodelet; + } } diff --git a/src/test/java/br/unicamp/meca/mind/MecaMindTest.java b/src/test/java/br/unicamp/meca/mind/MecaMindTest.java index 906cc4f..1db9b98 100644 --- a/src/test/java/br/unicamp/meca/mind/MecaMindTest.java +++ b/src/test/java/br/unicamp/meca/mind/MecaMindTest.java @@ -26,6 +26,7 @@ import br.unicamp.meca.mind.motivational.TestMotivationalFromPlanningCodelet; import br.unicamp.meca.mind.motor.TestMotorCodelet; import br.unicamp.meca.mind.perceptual.TestPerceptualCodelet; +import br.unicamp.meca.mind.planning.TestSoarCodelet; import br.unicamp.meca.mind.sensory.TestPerceptionSensoryCodelet; import br.unicamp.meca.mind.sensory.TestPlanningSensoryCodelet; import br.unicamp.meca.models.ActionSequencePlan; @@ -36,6 +37,7 @@ import br.unicamp.meca.system1.codelets.ISensoryCodelet; import br.unicamp.meca.system1.codelets.MotivationalCodelet; import br.unicamp.meca.system1.codelets.PerceptualCodelet; +import br.unicamp.meca.system2.codelets.IPlanningCodelet; /** * @author andre @@ -60,6 +62,8 @@ public class MecaMindTest { private static List motivationalCodelets; private static List activityCodelets; + + private static IPlanningCodelet planningCodelet; @BeforeClass public static void setup() throws InterruptedException { @@ -135,6 +139,8 @@ public static void setup() throws InterruptedException { Test1ActivityCodelet test1ActivityCodelet = new Test1ActivityCodelet("Test1Activity", perceptualPerceptionCodeletsIds, testMotivationalFromPerceptionCodeletIds, testMotorCodelet.getId(), null); activityCodelets.add(test1ActivityCodelet); + + planningCodelet = new TestSoarCodelet("soar"); /* @@ -145,6 +151,7 @@ public static void setup() throws InterruptedException { mecaMind.setPerceptualCodelets(perceptualCodelets); mecaMind.setMotivationalCodelets(motivationalCodelets); mecaMind.setActivityCodelets(activityCodelets); + mecaMind.setPlanningCodelet(planningCodelet); } diff --git a/src/test/java/br/unicamp/meca/mind/planning/TestSoarCodelet.java b/src/test/java/br/unicamp/meca/mind/planning/TestSoarCodelet.java new file mode 100644 index 0000000..dc6dfe7 --- /dev/null +++ b/src/test/java/br/unicamp/meca/mind/planning/TestSoarCodelet.java @@ -0,0 +1,49 @@ +/** + * + */ +package br.unicamp.meca.mind.planning; + +import java.io.File; + +import br.unicamp.meca.system2.codelets.SoarCodelet; + +/** + * @author andre + * + */ +public class TestSoarCodelet extends SoarCodelet { + + /** + * @param id + */ + public TestSoarCodelet(String id) { + super(id); + // TODO Auto-generated constructor stub + } + + /** + * @param id + * @param path_to_commands + * @param _agentName + * @param _productionPath + * @param startSOARDebugger + */ + public TestSoarCodelet(String id, String path_to_commands, String _agentName, File _productionPath, + Boolean startSOARDebugger) { + super(id, path_to_commands, _agentName, _productionPath, startSOARDebugger); + // TODO Auto-generated constructor stub + } + + @Override + public void fromPlanToAction() { + // TODO Auto-generated method stub + + } + + @Override + public void calculateActivation() { + // TODO Auto-generated method stub + + } + +} From 75cee55b357c13daa326fab20deab61f43b18116 Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Mon, 5 Apr 2021 17:26:58 -0300 Subject: [PATCH 39/89] Insertions on GoalCodelets --- build.gradle | 2 +- .../java/br/unicamp/meca/mind/MecaMind.java | 22 +++++++++--- .../meca/system2/codelets/GoalCodelet.java | 36 +++++++++++++++++++ 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index f3941ee..2068f77 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ description = "The Multipurpose Enhanced Cognitive Architecture (MECA)" sourceCompatibility = 1.8 targetCompatibility = 1.8 -version = '0.4.4' +version = '0.4.5' repositories { mavenCentral() diff --git a/src/main/java/br/unicamp/meca/mind/MecaMind.java b/src/main/java/br/unicamp/meca/mind/MecaMind.java index ae7f88a..97ba40c 100644 --- a/src/main/java/br/unicamp/meca/mind/MecaMind.java +++ b/src/main/java/br/unicamp/meca/mind/MecaMind.java @@ -86,7 +86,7 @@ public class MecaMind extends Mind { private ExpectationCodelet expectationCodelet; private ConsciousnessCodelet consciousnessCodelet; private SoarCodelet soarCodelet; - private GoalCodelet goalCodelet; + private List goalCodelets; private AppraisalCodelet appraisalCodelet; private WorkingMemory workingMemory; @@ -156,6 +156,7 @@ public void mountMecaMind() { mountBehaviorCodelets(); mountActivityTrackingCodelet(); mountActivityCodelets(); + mountGoalCodelets(); mountModules(); mountMemoryGroups(); } @@ -480,6 +481,17 @@ private void mountWorkingMemory() { } } } + + private void mountGoalCodelets() { + if (getGoalCodelets() != null) { + if (goalCodelets != null) { + for (GoalCodelet gc : goalCodelets) { + gc.setActionSequencePlanRequestMemoryContainer(actionSequencePlanRequestMemoryContainer); + gc.setWm(workingMemory); + } + } + } + } /** * Sets the Sensory Codelets. @@ -625,8 +637,8 @@ public void setSoarCodelet(SoarCodelet soarCodelet) { * @param goalCodelet * the goalCodelet to set */ - public void setGoalCodelet(GoalCodelet goalCodelet) { - this.goalCodelet = goalCodelet; + public void setGoalCodelets(List goalCodelets) { + this.goalCodelets = goalCodelets; } /** @@ -711,8 +723,8 @@ public List getEmotionalCodelets() { * * @return the Goal Codelet. */ - public GoalCodelet getGoalCodelet() { - return goalCodelet; + public List getGoalCodelets() { + return goalCodelets; } /** diff --git a/src/main/java/br/unicamp/meca/system2/codelets/GoalCodelet.java b/src/main/java/br/unicamp/meca/system2/codelets/GoalCodelet.java index 1935283..b1b5d5d 100644 --- a/src/main/java/br/unicamp/meca/system2/codelets/GoalCodelet.java +++ b/src/main/java/br/unicamp/meca/system2/codelets/GoalCodelet.java @@ -12,6 +12,9 @@ ******************************************************************************/ package br.unicamp.meca.system2.codelets; +import br.unicamp.cst.core.entities.Memory; +import br.unicamp.meca.memory.WorkingMemory; + /** * This class represents MECA's Goal Codelet. Goals are created in MECA by the * Goal Codelet. The Goal Codelet uses the Current Perception in order to @@ -25,6 +28,9 @@ */ public abstract class GoalCodelet extends br.unicamp.cst.motivational.GoalCodelet { + private Memory actionSequencePlanRequestMemoryContainer; + private WorkingMemory wm; + /** * Creates a MECA's Goal Codelet. * @@ -34,4 +40,34 @@ public abstract class GoalCodelet extends br.unicamp.cst.motivational.GoalCodele public GoalCodelet(String id) { super(id); } + + /** + * @return the actionSequencePlanRequestMemoryContainer + */ + public Memory getActionSequencePlanRequestMemoryContainer() { + return actionSequencePlanRequestMemoryContainer; + } + + /** + * @param actionSequencePlanRequestMemoryContainer the actionSequencePlanRequestMemoryContainer to set + */ + public void setActionSequencePlanRequestMemoryContainer(Memory actionSequencePlanRequestMemoryContainer) { + this.actionSequencePlanRequestMemoryContainer = actionSequencePlanRequestMemoryContainer; + } + + /** + * @return the wm + */ + public WorkingMemory getWm() { + return wm; + } + + /** + * @param wm the wm to set + */ + public void setWm(WorkingMemory wm) { + this.wm = wm; + } + + } From f9cb4fed4473ac017b55f0a867ecd5e3563b4ff3 Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Mon, 5 Apr 2021 17:48:04 -0300 Subject: [PATCH 40/89] Merged changes from SoarCodelet to IPlanningCodelet --- build.gradle | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 715174e..5783e23 100644 --- a/build.gradle +++ b/build.gradle @@ -10,11 +10,7 @@ description = "The Multipurpose Enhanced Cognitive Architecture (MECA)" sourceCompatibility = 1.8 targetCompatibility = 1.8 -<<<<<<< HEAD -version = '0.4.5' -======= -version = '0.5.0' ->>>>>>> bd5e50b57aa52cbe74e30b1538ec35b86d0b9f8d +version = '0.5.1' repositories { mavenCentral() From 84efd32623144110c3d8169c174769d4677ce5bc Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Mon, 5 Apr 2021 18:59:50 -0300 Subject: [PATCH 41/89] Small corrections --- src/main/java/br/unicamp/meca/mind/MecaMind.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/br/unicamp/meca/mind/MecaMind.java b/src/main/java/br/unicamp/meca/mind/MecaMind.java index ef0857b..ba74726 100644 --- a/src/main/java/br/unicamp/meca/mind/MecaMind.java +++ b/src/main/java/br/unicamp/meca/mind/MecaMind.java @@ -625,7 +625,8 @@ public void setConsciousnessCodelet(ConsciousnessCodelet consciousnessCodelet) { /** * Sets the Soar Codelet. * - * @deprecated instead, add the SoarCodelet using the interface IPlanningCodelet + * @deprecated instead, add the SoarCodelet using the setPlannningCodelet method. + * The SoarCodelet implements the IPlanningCodelet interface * @param soarCodelet * the soarCodelet to set */ @@ -637,8 +638,8 @@ public void setSoarCodelet(SoarCodelet soarCodelet) { /** * Sets the Goal Codelet. * - * @param goalCodelet - * the goalCodelet to set + * @param goalCodelets + * the set of goalCodelets to be mounted */ public void setGoalCodelets(List goalCodelets) { this.goalCodelets = goalCodelets; From 170258a91246b0bff6392647cbf2c7a2012d25c6 Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Mon, 3 May 2021 12:10:06 -0300 Subject: [PATCH 42/89] Changes for the day --- build.gradle | 6 ++- .../java/br/unicamp/meca/mind/MecaMind.java | 43 +++++++++++++++++-- .../meca/system2/codelets/GoalCodelet.java | 14 ++++++ 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 5783e23..9e259e9 100644 --- a/build.gradle +++ b/build.gradle @@ -13,6 +13,9 @@ targetCompatibility = 1.8 version = '0.5.1' repositories { + flatDir { + dirs '../cst/build/libs' + } mavenCentral() maven { url 'https://jitpack.io' } maven { @@ -27,7 +30,8 @@ repositories { } dependencies { - api 'com.github.CST-Group:cst:0.6.1' + api 'com.github.CST-Group:cst:codelet-profiler-SNAPSHOT' + //api ':cst:0.6.2-full' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' testImplementation 'org.ros.rosjava_messages:rosjava_test_msgs:0.3.0' diff --git a/src/main/java/br/unicamp/meca/mind/MecaMind.java b/src/main/java/br/unicamp/meca/mind/MecaMind.java index ba74726..409a652 100644 --- a/src/main/java/br/unicamp/meca/mind/MecaMind.java +++ b/src/main/java/br/unicamp/meca/mind/MecaMind.java @@ -21,6 +21,7 @@ import br.unicamp.cst.core.entities.Codelet; import br.unicamp.cst.core.entities.Memory; +import br.unicamp.cst.core.entities.MemoryContainer; import br.unicamp.cst.core.entities.MemoryObject; import br.unicamp.cst.core.entities.Mind; import br.unicamp.meca.memory.WorkingMemory; @@ -106,11 +107,17 @@ public MecaMind() { createCodeletGroup("Motivational"); createCodeletGroup("Behavioral"); createCodeletGroup("ActivityTracking"); + createCodeletGroup("Attention"); + createCodeletGroup("Planning"); + createCodeletGroup("Goal"); createMemoryGroup("Sensors"); createMemoryGroup("Actuators"); createMemoryGroup("Percepts"); createMemoryGroup("Drives"); createMemoryGroup("Plans"); + createMemoryGroup("Goal"); + createMemoryGroup("Attention"); + createMemoryGroup("Planning"); } /** @@ -129,11 +136,17 @@ public MecaMind(String id) { createCodeletGroup("Motivational"); createCodeletGroup("Behavioral"); createCodeletGroup("ActivityTracking"); + createCodeletGroup("Attention"); + createCodeletGroup("Planning"); + createCodeletGroup("Goal"); createMemoryGroup("Sensors"); createMemoryGroup("Actuators"); createMemoryGroup("Percepts"); createMemoryGroup("Drives"); createMemoryGroup("Plans"); + createMemoryGroup("Goal"); + createMemoryGroup("Attention"); + createMemoryGroup("Planning"); } /** @@ -486,10 +499,32 @@ private void mountWorkingMemory() { private void mountGoalCodelets() { if (getGoalCodelets() != null) { if (goalCodelets != null) { - for (GoalCodelet gc : goalCodelets) { - gc.setActionSequencePlanRequestMemoryContainer(actionSequencePlanRequestMemoryContainer); - gc.setWm(workingMemory); - } + // Create the Goal Memory Container + //MemoryContainer goalMemoryContainer = createMemoryContainer("OUTPUT_GOAL_MEMORY"); + MemoryContainer goalMemoryContainer = createMemoryContainer("Goals"); + registerMemory(goalMemoryContainer,"Goal"); + //MemoryObject wmem = createMemoryObject("INPUT_HYPOTHETICAL_SITUATIONS_MEMORY"); + //registerMemory(wmem,"Goal"); + //wmem.setI(workingMemory.getCurrentPerceptionMemory().getI()); + for (GoalCodelet gc : goalCodelets) { + // Insert the Goal Codelet in the Coderack + insertCodelet(gc); + // Mount internal variables + gc.setActionSequencePlanRequestMemoryContainer(actionSequencePlanRequestMemoryContainer); + gc.setWm(workingMemory); + // Mount input + gc.setInputHypotheticalSituationsMO(workingMemory.getCurrentPerceptionMemory()); + + registerMemory(workingMemory.getCurrentPerceptionMemory(),"Goal"); + gc.addInput(actionSequencePlanRequestMemoryContainer); + gc.addInput(workingMemory.getCurrentPerceptionMemory()); + //gc.addInput(wmem); + // Mount output + gc.setGoalMO(goalMemoryContainer); + goalMemoryContainer.setI(null,0.0,gc.getId()); + gc.addOutput(goalMemoryContainer); + //gc.addOutput(wmem); + } } } } diff --git a/src/main/java/br/unicamp/meca/system2/codelets/GoalCodelet.java b/src/main/java/br/unicamp/meca/system2/codelets/GoalCodelet.java index b1b5d5d..c249aac 100644 --- a/src/main/java/br/unicamp/meca/system2/codelets/GoalCodelet.java +++ b/src/main/java/br/unicamp/meca/system2/codelets/GoalCodelet.java @@ -13,6 +13,8 @@ package br.unicamp.meca.system2.codelets; import br.unicamp.cst.core.entities.Memory; +import br.unicamp.cst.core.entities.MemoryContainer; +import br.unicamp.cst.representation.owrl.AbstractObject; import br.unicamp.meca.memory.WorkingMemory; /** @@ -39,8 +41,20 @@ public abstract class GoalCodelet extends br.unicamp.cst.motivational.GoalCodele */ public GoalCodelet(String id) { super(id); + setName(id); } + @Override + public void proc() { + if (isInit()) { + setHypotheticalSituation((AbstractObject) getInputHypotheticalSituationsMO().getI()); + setGoal(goalGeneration(getHypotheticalSituation())); + ((MemoryContainer)getGoalMO()).setI(getGoal(),getActivation(),getId()); + } + + setInit(true); + } + /** * @return the actionSequencePlanRequestMemoryContainer */ From c1180bd8902d6369d23007213d6ab85b6fbfe887 Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Thu, 6 May 2021 01:41:33 -0300 Subject: [PATCH 43/89] Corrections after changes from AbstractObject to Idea in many points --- build.gradle | 19 +- gradle.properties | 2 + .../br/unicamp/meca/memory/WorkingMemory.java | 443 ++++++++++-------- .../java/br/unicamp/meca/mind/MecaMind.java | 12 +- .../system1/codelets/AttentionCodelet.java | 24 +- .../meca/system2/codelets/GoalCodelet.java | 4 +- .../meca/system2/codelets/SoarCodelet.java | 103 ++-- 7 files changed, 332 insertions(+), 275 deletions(-) diff --git a/build.gradle b/build.gradle index 9e259e9..d4fa2a8 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java-library-distribution' id 'jacoco' - id 'maven' + id 'maven-publish' } group = 'com.github.CST-Group' @@ -22,19 +22,28 @@ repositories { url "https://github.com/rosjava/rosjava_mvn_repo/raw/master" } maven { - url "http://repository.springsource.com/maven/bundles/release" + url "https://repository.springsource.com/maven/bundles/release" } maven { - url "http://repository.springsource.com/maven/bundles/external" + url "https://repository.springsource.com/maven/bundles/external" } } dependencies { - api 'com.github.CST-Group:cst:codelet-profiler-SNAPSHOT' - //api ':cst:0.6.2-full' + //api group: "com.github.CST-Group", name: "cst", version: "codelet-tracking-SNAPSHOT", changing: true + + + //api('com.github.CST-Group:cst:ed2f1838dbfd7c46a7cbf2e922bc9a53e0a4e44c') + api ':cst:0.6.2-full' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' testImplementation 'org.ros.rosjava_messages:rosjava_test_msgs:0.3.0' + +} + +// forces all changing dependencies (i.e. SNAPSHOTs) to automagicially download +configurations.all { + resolutionStrategy.cacheChangingModulesFor 0, 'seconds' } jar { diff --git a/gradle.properties b/gradle.properties index 8bd86f6..1d4c225 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1,3 @@ org.gradle.jvmargs=-Xmx1536M +action.custom-1=uberJar +action.custom-1.args=uberJar diff --git a/src/main/java/br/unicamp/meca/memory/WorkingMemory.java b/src/main/java/br/unicamp/meca/memory/WorkingMemory.java index 635a82b..98bd620 100644 --- a/src/main/java/br/unicamp/meca/memory/WorkingMemory.java +++ b/src/main/java/br/unicamp/meca/memory/WorkingMemory.java @@ -15,6 +15,8 @@ import br.unicamp.cst.core.entities.Memory; import br.unicamp.cst.core.entities.MemoryContainer; import br.unicamp.cst.core.entities.MemoryObject; +import java.util.HashMap; +import java.util.Map; /** * This class represents the MECA's Working Memory. @@ -106,20 +108,22 @@ public class WorkingMemory { * The Working Memory Input constant. */ public static final String WORKING_MEMORY_INPUT = "WORKING_MEMORY_INPUT"; + + private Map wm = new HashMap(); private String id; - private Memory cueMemory; - private Memory plansMemory; - private Memory episodicRecallMemory; - private Memory globalWorkspaceMemory; - private Memory executivePlanMemory; - - private Memory imaginationsMemory; - private Memory goalsMemory; - private Memory currentPerceptionMemory; - private Memory predictedSituationMemory; - - private Memory nextActionMemory; +// private Memory cueMemory; +// private Memory plansMemory; +// private Memory episodicRecallMemory; +// private Memory globalWorkspaceMemory; +// private Memory executivePlanMemory; +// +// private Memory imaginationsMemory; +// private Memory goalsMemory; +// private Memory currentPerceptionMemory; +// private Memory predictedSituationMemory; +// +// private Memory nextActionMemory; /** * Creates the MECA's Working Memory. @@ -130,17 +134,28 @@ public class WorkingMemory { public WorkingMemory(String id) { setId(id); - setPlansMemory(new MemoryContainer()); - setEpisodicRecallMemory(new MemoryContainer()); - setGlobalWorkspaceMemory(new MemoryContainer()); - setImaginationsMemory(new MemoryContainer()); - setGoalsMemory(new MemoryContainer()); + setInternalMemory("PlansMemory",new MemoryContainer("PlansMemory")); + setInternalMemory("EpisodicRecallMemory",new MemoryContainer("EpisodicRecallMemory")); + setInternalMemory("GlobalWorkspaceMemory",new MemoryContainer("GlobalWorkspaceMemory")); + setInternalMemory("ImaginationsMemory",new MemoryContainer("ImaginationsMemory")); + setInternalMemory("GoalsMemory",new MemoryContainer("GoalsMemory")); + +// setPlansMemory(new MemoryContainer()); +// setEpisodicRecallMemory(new MemoryContainer()); +// setGlobalWorkspaceMemory(new MemoryContainer()); +// setImaginationsMemory(new MemoryContainer()); +// setGoalsMemory(new MemoryContainer()); - setCueMemory(new MemoryObject()); - setNextActionMemory(new MemoryObject()); - setExecutivePlanMemory(new MemoryObject()); - setCurrentPerceptionMemory(new MemoryObject()); - setPredictedSituationMemory(new MemoryObject()); + setInternalMemory("CueMemory",new MemoryContainer("CueMemory")); + setInternalMemory("NextActionMemory",new MemoryContainer("NextActionMemory")); + setInternalMemory("ExecutivePlanMemory",new MemoryContainer("ExecutivePlanMemory")); + setInternalMemory("CurrentPerceptionMemory",new MemoryContainer("CurrentPerceptionMemory")); + setInternalMemory("PredictedSituationMemory",new MemoryContainer("PredictedSituationMemory")); +// setCueMemory(new MemoryObject()); +// setNextActionMemory(new MemoryObject()); +// setExecutivePlanMemory(new MemoryObject()); +// setCurrentPerceptionMemory(new MemoryObject()); +// setPredictedSituationMemory(new MemoryObject()); } /** @@ -162,193 +177,215 @@ public void setId(String id) { this.id = id; } - /** - * Gets the Cue Memory. - * - * @return the Cue Memory. - */ - public Memory getCueMemory() { - return cueMemory; - } - - /** - * Sets the Cue Memory. - * - * @param cueMemory - * the Cue memory to set. - */ - public void setCueMemory(Memory cueMemory) { - this.cueMemory = cueMemory; - } - - /** - * Gets the Plans Memory. - * - * @return the Plans Memory. - */ - public Memory getPlansMemory() { - return plansMemory; - } - - /** - * Sets the Plans Memory. - * - * @param plansMemory - * the plans Memory to set. - */ - public void setPlansMemory(Memory plansMemory) { - this.plansMemory = plansMemory; - } - - /** - * Gets the Episodic Recall Memory. - * - * @return the Episodic Recall Memory. - */ - public Memory getEpisodicRecallMemory() { - return episodicRecallMemory; - } - - /** - * Sets the Episodic Recall Memory - * - * @param episodicRecallMemory - * the Episodic Recall Memory to set. - */ - public void setEpisodicRecallMemory(Memory episodicRecallMemory) { - this.episodicRecallMemory = episodicRecallMemory; - } - - /** - * Gets the Global Workspace Memory - * - * @return the Global Workspace Memory. - */ - public Memory getGlobalWorkspaceMemory() { - return globalWorkspaceMemory; - } - - /** - * Sets the Global Workspace Memory - * - * @param globalWorkspaceMemory - * the Global Workspace memory to set. - */ - public void setGlobalWorkspaceMemory(Memory globalWorkspaceMemory) { - this.globalWorkspaceMemory = globalWorkspaceMemory; - } - - /** - * Gets the Executive Plan Memory. - * - * @return the Executive Plan Memory. - */ - public Memory getExecutivePlanMemory() { - return executivePlanMemory; - } - - /** - * Sets the Executive Plan memory. - * - * @param executivePlanMemory - * the Executive Plan Memory to set. - */ - public void setExecutivePlanMemory(Memory executivePlanMemory) { - this.executivePlanMemory = executivePlanMemory; - } - - /** - * Gets the Imaginations Memory. - * - * @return the Imaginations Memory. - */ - public Memory getImaginationsMemory() { - return imaginationsMemory; - } - - /** - * Sets the Imaginations memory. - * - * @param imaginationsMemory - * the imaginations memory to set. - */ - public void setImaginationsMemory(Memory imaginationsMemory) { - this.imaginationsMemory = imaginationsMemory; - } - - /** - * Gets the Goals Memory. - * - * @return the Goals Memory. - */ - public Memory getGoalsMemory() { - return goalsMemory; - } - - /** - * Sets the Goals Memory. - * - * @param goalsMemory - * the Goals Memory to set. - */ - public void setGoalsMemory(Memory goalsMemory) { - this.goalsMemory = goalsMemory; - } - - /** - * Gets the Current Perception Memory. - * - * @return the current perception memory. - */ - public Memory getCurrentPerceptionMemory() { - return currentPerceptionMemory; - } - - /** - * Sets the current perception memory. - * - * @param currentPerceptionMemory - * the current perception memory to set. - */ - public void setCurrentPerceptionMemory(Memory currentPerceptionMemory) { - this.currentPerceptionMemory = currentPerceptionMemory; - } - - /** - * Gets the predicted situation memory. - * - * @return the predicte situation memory. - */ - public Memory getPredictedSituationMemory() { - return predictedSituationMemory; - } - - /** - * Sets the predicted situation memory. - * - * @param predictedSituationMemory - * the predicted situation memory to set. - */ - public void setPredictedSituationMemory(Memory predictedSituationMemory) { - this.predictedSituationMemory = predictedSituationMemory; - } - - /** - * Gets the next action memory. + /** + * Gets an Internal Sub Memory. * - * @return the next action memory. + * @param memName the name of the internal memory to get + * @return the Internal Memory. */ - public Memory getNextActionMemory() { - return nextActionMemory; + public Memory getInternalMemory(String memName) { + return(wm.get(memName)); } /** - * Sets the next action memory. + * Sets an Internal Memory. * - * @param nextActionMemory - * the next action memory to set. + * @param memName the name of the internal memory + * @param memory the memory to be set */ - public void setNextActionMemory(Memory nextActionMemory) { - this.nextActionMemory = nextActionMemory; + public void setInternalMemory(String memName, Memory memory) { + if (wm.containsKey(wm)) + wm.replace(memName, memory); + else wm.put(memName, memory); } + +// /** +// * Gets the Cue Memory. +// * +// * @return the Cue Memory. +// */ +// public Memory getCueMemory() { +// return cueMemory; +// } +// +// /** +// * Sets the Cue Memory. +// * +// * @param cueMemory +// * the Cue memory to set. +// */ +// public void setCueMemory(Memory cueMemory) { +// this.cueMemory = cueMemory; +// } +// +// /** +// * Gets the Plans Memory. +// * +// * @return the Plans Memory. +// */ +// public Memory getPlansMemory() { +// return plansMemory; +// } +// +// /** +// * Sets the Plans Memory. +// * +// * @param plansMemory +// * the plans Memory to set. +// */ +// public void setPlansMemory(Memory plansMemory) { +// this.plansMemory = plansMemory; +// } +// +// /** +// * Gets the Episodic Recall Memory. +// * +// * @return the Episodic Recall Memory. +// */ +// public Memory getEpisodicRecallMemory() { +// return episodicRecallMemory; +// } +// +// /** +// * Sets the Episodic Recall Memory +// * +// * @param episodicRecallMemory +// * the Episodic Recall Memory to set. +// */ +// public void setEpisodicRecallMemory(Memory episodicRecallMemory) { +// this.episodicRecallMemory = episodicRecallMemory; +// } +// +// /** +// * Gets the Global Workspace Memory +// * +// * @return the Global Workspace Memory. +// */ +// public Memory getGlobalWorkspaceMemory() { +// return globalWorkspaceMemory; +// } +// +// /** +// * Sets the Global Workspace Memory +// * +// * @param globalWorkspaceMemory +// * the Global Workspace memory to set. +// */ +// public void setGlobalWorkspaceMemory(Memory globalWorkspaceMemory) { +// this.globalWorkspaceMemory = globalWorkspaceMemory; +// } +// +// /** +// * Gets the Executive Plan Memory. +// * +// * @return the Executive Plan Memory. +// */ +// public Memory getExecutivePlanMemory() { +// return executivePlanMemory; +// } +// +// /** +// * Sets the Executive Plan memory. +// * +// * @param executivePlanMemory +// * the Executive Plan Memory to set. +// */ +// public void setExecutivePlanMemory(Memory executivePlanMemory) { +// this.executivePlanMemory = executivePlanMemory; +// } +// +// /** +// * Gets the Imaginations Memory. +// * +// * @return the Imaginations Memory. +// */ +// public Memory getImaginationsMemory() { +// return imaginationsMemory; +// } +// +// /** +// * Sets the Imaginations memory. +// * +// * @param imaginationsMemory +// * the imaginations memory to set. +// */ +// public void setImaginationsMemory(Memory imaginationsMemory) { +// this.imaginationsMemory = imaginationsMemory; +// } +// +// /** +// * Gets the Goals Memory. +// * +// * @return the Goals Memory. +// */ +// public Memory getGoalsMemory() { +// return goalsMemory; +// } +// +// /** +// * Sets the Goals Memory. +// * +// * @param goalsMemory +// * the Goals Memory to set. +// */ +// public void setGoalsMemory(Memory goalsMemory) { +// this.goalsMemory = goalsMemory; +// } +// +// /** +// * Gets the Current Perception Memory. +// * +// * @return the current perception memory. +// */ +// public Memory getCurrentPerceptionMemory() { +// return currentPerceptionMemory; +// } +// +// /** +// * Sets the current perception memory. +// * +// * @param currentPerceptionMemory +// * the current perception memory to set. +// */ +// public void setCurrentPerceptionMemory(Memory currentPerceptionMemory) { +// this.currentPerceptionMemory = currentPerceptionMemory; +// } +// +// /** +// * Gets the predicted situation memory. +// * +// * @return the predicte situation memory. +// */ +// public Memory getPredictedSituationMemory() { +// return predictedSituationMemory; +// } +// +// /** +// * Sets the predicted situation memory. +// * +// * @param predictedSituationMemory +// * the predicted situation memory to set. +// */ +// public void setPredictedSituationMemory(Memory predictedSituationMemory) { +// this.predictedSituationMemory = predictedSituationMemory; +// } +// +// /** +// * Gets the next action memory. +// * +// * @return the next action memory. +// */ +// public Memory getNextActionMemory() { +// return nextActionMemory; +// } +// +// /** +// * Sets the next action memory. +// * +// * @param nextActionMemory +// * the next action memory to set. +// */ +// public void setNextActionMemory(Memory nextActionMemory) { +// this.nextActionMemory = nextActionMemory; +// } } diff --git a/src/main/java/br/unicamp/meca/mind/MecaMind.java b/src/main/java/br/unicamp/meca/mind/MecaMind.java index 409a652..b565443 100644 --- a/src/main/java/br/unicamp/meca/mind/MecaMind.java +++ b/src/main/java/br/unicamp/meca/mind/MecaMind.java @@ -491,7 +491,8 @@ private void mountPlanningCodelet() { private void mountWorkingMemory() { if (getWorkingMemory() != null) { if (attentionCodeletSystem1 != null) { - getWorkingMemory().setCurrentPerceptionMemory(attentionCodeletSystem1.getOutputFilteredPerceptsMO()); + //getWorkingMemory().setCurrentPerceptionMemory(attentionCodeletSystem1.getOutputFilteredPerceptsMO()); + getWorkingMemory().setInternalMemory("CurrentPerceptionMemory",attentionCodeletSystem1.getOutputFilteredPerceptsMO()); } } } @@ -513,11 +514,14 @@ private void mountGoalCodelets() { gc.setActionSequencePlanRequestMemoryContainer(actionSequencePlanRequestMemoryContainer); gc.setWm(workingMemory); // Mount input - gc.setInputHypotheticalSituationsMO(workingMemory.getCurrentPerceptionMemory()); + //gc.setInputHypotheticalSituationsMO(workingMemory.getCurrentPerceptionMemory()); + gc.setInputHypotheticalSituationsMO(workingMemory.getInternalMemory("CurrentPerceptionMemory")); - registerMemory(workingMemory.getCurrentPerceptionMemory(),"Goal"); + //registerMemory(workingMemory.getCurrentPerceptionMemory(),"Goal"); + registerMemory(workingMemory.getInternalMemory("CurrentPerceptionMemory"),"Goal"); gc.addInput(actionSequencePlanRequestMemoryContainer); - gc.addInput(workingMemory.getCurrentPerceptionMemory()); + //gc.addInput(workingMemory.getCurrentPerceptionMemory()); + gc.addInput(workingMemory.getInternalMemory("CurrentPerceptionMemory")); //gc.addInput(wmem); // Mount output gc.setGoalMO(goalMemoryContainer); diff --git a/src/main/java/br/unicamp/meca/system1/codelets/AttentionCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/AttentionCodelet.java index 157892d..2a6439e 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/AttentionCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/AttentionCodelet.java @@ -18,7 +18,7 @@ import br.unicamp.cst.core.entities.Codelet; import br.unicamp.cst.core.entities.Memory; import br.unicamp.cst.core.exceptions.CodeletActivationBoundsException; -import br.unicamp.cst.representation.owrl.AbstractObject; +import br.unicamp.cst.representation.wme.Idea; /** * This class represents a MECA Attention Codelet in System 1. Attention @@ -44,8 +44,8 @@ public abstract class AttentionCodelet extends Codelet { private Memory inputPerceptsMO; private Memory outputFilteredPerceptsMO; - private List inputPercepts; - private AbstractObject outputFilteredPercepts; + private List inputPercepts; + private Idea outputFilteredPercepts; private List perceptualCodeletsIds; /** @@ -62,7 +62,7 @@ public AttentionCodelet(String id, ArrayList perceptualCodeletsIds) { setName(id); setId(id); setPerceptualCodeletsIds(perceptualCodeletsIds); - setInputPercepts(new ArrayList()); + setInputPercepts(new ArrayList()); } @Override @@ -70,7 +70,7 @@ public void accessMemoryObjects() { if (getInputPerceptsMO() == null) { for (Memory perceptualMO : this.getInputs()) { - getInputPercepts().add((AbstractObject) perceptualMO.getI()); + getInputPercepts().add((Idea) perceptualMO.getI()); } } @@ -96,13 +96,13 @@ public void proc() { } /** - * Generates a filtered percept as an AbstractObject. + * Generates a filtered percept as an Idea. * * @param inputPercepts * the list of input percepts. - * @return filtered percept as an AbstractObject. + * @return filtered percept as an Idea. */ - public abstract AbstractObject generateFilteredPercepts(List inputPercepts); + public abstract Idea generateFilteredPercepts(List inputPercepts); /** * Gets the input Percept as a Memory Object. @@ -147,7 +147,7 @@ public void setOutputFilteredPerceptsMO(Memory outputFilteredPerceptsMO) { * * @return the list of input percepts. */ - public List getInputPercepts() { + public List getInputPercepts() { return inputPercepts; } @@ -157,7 +157,7 @@ public List getInputPercepts() { * @param inputPercepts * the list of input percepts. */ - public void setInputPercepts(List inputPercepts) { + public void setInputPercepts(List inputPercepts) { this.inputPercepts = inputPercepts; } @@ -166,7 +166,7 @@ public void setInputPercepts(List inputPercepts) { * * @return the output filtered percepts. */ - public AbstractObject getOutputFilteredPercepts() { + public Idea getOutputFilteredPercepts() { return outputFilteredPercepts; } @@ -176,7 +176,7 @@ public AbstractObject getOutputFilteredPercepts() { * @param outputFilteredPercepts * the output filtered percepts. */ - public void setOutputFilteredPercepts(AbstractObject outputFilteredPercepts) { + public void setOutputFilteredPercepts(Idea outputFilteredPercepts) { this.outputFilteredPercepts = outputFilteredPercepts; } diff --git a/src/main/java/br/unicamp/meca/system2/codelets/GoalCodelet.java b/src/main/java/br/unicamp/meca/system2/codelets/GoalCodelet.java index c249aac..19678e5 100644 --- a/src/main/java/br/unicamp/meca/system2/codelets/GoalCodelet.java +++ b/src/main/java/br/unicamp/meca/system2/codelets/GoalCodelet.java @@ -14,7 +14,7 @@ import br.unicamp.cst.core.entities.Memory; import br.unicamp.cst.core.entities.MemoryContainer; -import br.unicamp.cst.representation.owrl.AbstractObject; +import br.unicamp.cst.representation.wme.Idea; import br.unicamp.meca.memory.WorkingMemory; /** @@ -47,7 +47,7 @@ public GoalCodelet(String id) { @Override public void proc() { if (isInit()) { - setHypotheticalSituation((AbstractObject) getInputHypotheticalSituationsMO().getI()); + setHypotheticalSituation((Idea) getInputHypotheticalSituationsMO().getI()); setGoal(goalGeneration(getHypotheticalSituation())); ((MemoryContainer)getGoalMO()).setI(getGoal(),getActivation(),getId()); } diff --git a/src/main/java/br/unicamp/meca/system2/codelets/SoarCodelet.java b/src/main/java/br/unicamp/meca/system2/codelets/SoarCodelet.java index 73ce799..4b137ae 100644 --- a/src/main/java/br/unicamp/meca/system2/codelets/SoarCodelet.java +++ b/src/main/java/br/unicamp/meca/system2/codelets/SoarCodelet.java @@ -19,8 +19,7 @@ import br.unicamp.cst.core.entities.Memory; import br.unicamp.cst.motivational.Goal; -import br.unicamp.cst.representation.owrl.AbstractObject; -import br.unicamp.cst.representation.owrl.Property; +import br.unicamp.cst.representation.wme.Idea; import br.unicamp.meca.memory.WorkingMemory; /** @@ -110,11 +109,11 @@ public void accessMemoryObjects() { @Override public void proc() { - AbstractObject il = processWorkingMemoryInput(); - if (il.getCompositeList().size() == 0) + Idea il = processWorkingMemoryInput(); + if (il.getL().size() == 0) return; - setInputLinkAO(il); + this.setInputLinkIdea(il); if (getDebugState() == 0) getJsoar().step(); @@ -124,7 +123,8 @@ public void proc() { if (commandList != null) { Collections.addAll(rawPlan, commandList); - workingMemory.getPlansMemory().setI(rawPlan); + //workingMemory.getPlansMemory().setI(rawPlan); + workingMemory.getInternalMemory("PlansMemory").setI(rawPlan); workingMemoryOutputMO.setI(workingMemory); @@ -147,44 +147,49 @@ public void proc() { * * @return an abstract object represent an Input link. */ - public AbstractObject processWorkingMemoryInput() { + public Idea processWorkingMemoryInput() { - AbstractObject il = new AbstractObject("InputLink"); + Idea il = new Idea("InputLink"); - AbstractObject currentPerceptionWO = (AbstractObject) workingMemory.getCurrentPerceptionMemory().getI() != null - ? convertToAbstractObject((AbstractObject) workingMemory.getCurrentPerceptionMemory().getI(), + //AbstractObject currentPerceptionWO = (AbstractObject) workingMemory.getCurrentPerceptionMemory().getI() != null + Idea currentPerceptionWO = (Idea) workingMemory.getInternalMemory("CurrentPerceptionMemory").getI() != null + ? convertToIdea((Idea) workingMemory.getInternalMemory("CurrentPerceptionMemory").getI(), "CURRENT_PERCEPTION") : null; - AbstractObject imaginationsWO = (List) workingMemory.getImaginationsMemory().getI() != null - ? convertToAbstractObject((List) workingMemory.getImaginationsMemory().getI(), + //AbstractObject imaginationsWO = (List) workingMemory.getImaginationsMemory().getI() != null + Idea imaginationsWO = (List) workingMemory.getInternalMemory("ImaginationsMemory").getI() != null + ? convertToIdea((List) workingMemory.getInternalMemory("ImaginationsMemory").getI(), "IMAGINATION") : null; - AbstractObject goalsWO = (List) workingMemory.getGoalsMemory().getI() != null - ? goalToAbstractObject((List) workingMemory.getGoalsMemory().getI()) : null; + //AbstractObject goalsWO = (List) workingMemory.getGoalsMemory().getI() != null + Idea goalsWO = (List) workingMemory.getInternalMemory("GoalsMemory").getI() != null + ? goalToIdea((List) workingMemory.getInternalMemory("GoalsMemory").getI()) : null; - AbstractObject globalWO = (List) workingMemory.getGlobalWorkspaceMemory().getI() != null - ? globalWorkspaceToAbstractObject((List) workingMemory.getGlobalWorkspaceMemory().getI()) + //AbstractObject globalWO = (List) workingMemory.getGlobalWorkspaceMemory().getI() != null + Idea globalWO = (List) workingMemory.getInternalMemory("GlobalWorkspaceMemory").getI() != null + ? globalWorkspaceToIdea((List) workingMemory.getInternalMemory("GlobalWorkspaceMemory").getI()) : null; - AbstractObject epRecallWO = (List) workingMemory.getEpisodicRecallMemory().getI() != null - ? epRecallToAbstractObject((List) workingMemory.getEpisodicRecallMemory().getI()) : null; + //AbstractObject epRecallWO = (List) workingMemory.getEpisodicRecallMemory().getI() != null + Idea epRecallWO = (List) workingMemory.getInternalMemory("EpisodicRecallMemory").getI() != null + ? epRecallToIdea((List) workingMemory.getInternalMemory("EpisodicRecallMemory").getI()) : null; if (currentPerceptionWO != null) - il.addCompositePart(currentPerceptionWO); + il.add(currentPerceptionWO); if (imaginationsWO != null) - il.addCompositePart(imaginationsWO); + il.add(imaginationsWO); if (goalsWO != null) - il.addCompositePart(goalsWO); + il.add(goalsWO); if (globalWO != null) - il.addCompositePart(globalWO); + il.add(globalWO); if (epRecallWO != null) - il.addCompositePart(epRecallWO); + il.add(epRecallWO); return il; } @@ -198,11 +203,11 @@ public AbstractObject processWorkingMemoryInput() { * the node name. * @return the abstract object. */ - public AbstractObject convertToAbstractObject(AbstractObject abstractObject, String nodeName) { + public Idea convertToIdea(Idea abstractObject, String nodeName) { - AbstractObject abs = new AbstractObject(nodeName); + Idea abs = new Idea(nodeName); - abs.addCompositePart(abstractObject); + abs.add(abstractObject); return abs; } @@ -210,18 +215,18 @@ public AbstractObject convertToAbstractObject(AbstractObject abstractObject, Str /** * Converts to abstract object. * - * @param abstractObjects + * @param ideas * the list of input abstract objects. * @param nodeNameTemplate * the node name template. * @return the abstract object. */ - public AbstractObject convertToAbstractObject(List abstractObjects, String nodeNameTemplate) { + public Idea convertToIdea(List ideas, String nodeNameTemplate) { - AbstractObject configs = new AbstractObject(abstractObjects.toString()); + Idea configs = new Idea(ideas.toString()); - for (AbstractObject abs : abstractObjects) { - configs.addAggregatePart(convertToAbstractObject(abs, nodeNameTemplate)); + for (Idea abs : ideas) { + configs.add(convertToIdea(abs, nodeNameTemplate)); } return configs; } @@ -233,15 +238,15 @@ public AbstractObject convertToAbstractObject(List abstractObjec * the list of goals. * @return the Abstract Object representing the Goals. */ - public AbstractObject goalToAbstractObject(List goals) { + public Idea goalToIdea(List goals) { - AbstractObject go = new AbstractObject("Goals"); + Idea go = new Idea("Goals"); for (Goal goal : goals) { - AbstractObject temp = convertToAbstractObject(goal.getGoalAbstractObjects(), "GOAL"); - temp.addProperty(new Property(goal.getId())); - go.addAggregatePart(temp); + Idea temp = convertToIdea(goal.getGoalIdeas(), "GOAL"); + temp.add(new Idea(goal.getId())); + go.add(temp); } return go; } @@ -253,17 +258,17 @@ public AbstractObject goalToAbstractObject(List goals) { * the list of memories * @return the abstract object representing global workspace */ - public AbstractObject globalWorkspaceToAbstractObject(List global) { + public Idea globalWorkspaceToIdea(List global) { - List globalAbstractObjects = null; + List globalIdeass = null; List globalStrings = null; for (Memory mem : global) { - if (isAbstractObject(mem.getI())) { + if (isIdea(mem.getI())) { - globalAbstractObjects.add((AbstractObject) mem.getI()); + globalIdeass.add((Idea) mem.getI()); } } @@ -275,11 +280,11 @@ public AbstractObject globalWorkspaceToAbstractObject(List global) { } } - AbstractObject gAbs = convertToAbstractObject(globalAbstractObjects, "GLOBAL_WORKSPACE"); + Idea gAbs = convertToIdea(globalIdeass, "GLOBAL_WORKSPACE"); for (String st : globalStrings) { - gAbs.addAggregatePart(new AbstractObject(st)); + gAbs.add(new Idea(st)); } return gAbs; @@ -292,19 +297,19 @@ public AbstractObject globalWorkspaceToAbstractObject(List global) { * the list of memories representing the episodic recall. * @return the Abstract Object representing an episodic recall. */ - public AbstractObject epRecallToAbstractObject(List episodicRecall) { + public Idea epRecallToIdea(List episodicRecall) { - List epConfigurations = null; + List epConfigurations = null; for (Memory mem : episodicRecall) { - if (isAbstractObject(mem.getI())) { + if (isIdea(mem.getI())) { - epConfigurations.add((AbstractObject) mem.getI()); + epConfigurations.add((Idea) mem.getI()); } } - AbstractObject gConf = convertToAbstractObject(epConfigurations, "EPISODIC_RECALL_MEMORY"); + Idea gConf = convertToIdea(epConfigurations, "EPISODIC_RECALL_MEMORY"); return gConf; } @@ -316,9 +321,9 @@ public AbstractObject epRecallToAbstractObject(List episodicRecall) { * the object to be tested * @return true if the obj is an abstract object. */ - public boolean isAbstractObject(Object obj) { + public boolean isIdea(Object obj) { - if (obj.getClass() == AbstractObject.class) + if (obj.getClass() == Idea.class) return true; else return false; From 9bc068798be0ff2bc90b7a9fe4c059abd8470402 Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Sun, 16 May 2021 16:54:43 -0300 Subject: [PATCH 44/89] many corrections to make it compatible with new CST --- build.gradle | 4 +-- .../br/unicamp/meca/memory/WorkingMemory.java | 11 +++++++- .../java/br/unicamp/meca/mind/MecaMind.java | 19 +++++++++++--- .../meca/system2/codelets/SoarCodelet.java | 26 +++++++++---------- 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/build.gradle b/build.gradle index d4fa2a8..ec94ca6 100644 --- a/build.gradle +++ b/build.gradle @@ -33,8 +33,8 @@ dependencies { //api group: "com.github.CST-Group", name: "cst", version: "codelet-tracking-SNAPSHOT", changing: true - //api('com.github.CST-Group:cst:ed2f1838dbfd7c46a7cbf2e922bc9a53e0a4e44c') - api ':cst:0.6.2-full' + api('com.github.CST-Group:cst:29b3611') + //api ':cst:0.6.2-full' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' testImplementation 'org.ros.rosjava_messages:rosjava_test_msgs:0.3.0' diff --git a/src/main/java/br/unicamp/meca/memory/WorkingMemory.java b/src/main/java/br/unicamp/meca/memory/WorkingMemory.java index 98bd620..ebef889 100644 --- a/src/main/java/br/unicamp/meca/memory/WorkingMemory.java +++ b/src/main/java/br/unicamp/meca/memory/WorkingMemory.java @@ -14,8 +14,9 @@ import br.unicamp.cst.core.entities.Memory; import br.unicamp.cst.core.entities.MemoryContainer; -import br.unicamp.cst.core.entities.MemoryObject; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -199,6 +200,14 @@ public void setInternalMemory(String memName, Memory memory) { else wm.put(memName, memory); } + public List getInternalMemoryNames() { + ArrayList imn = new ArrayList<>(); + for (String s : wm.keySet()) { + imn.add(s); + } + return imn; + } + // /** // * Gets the Cue Memory. // * diff --git a/src/main/java/br/unicamp/meca/mind/MecaMind.java b/src/main/java/br/unicamp/meca/mind/MecaMind.java index b565443..5d8feb3 100644 --- a/src/main/java/br/unicamp/meca/mind/MecaMind.java +++ b/src/main/java/br/unicamp/meca/mind/MecaMind.java @@ -118,6 +118,10 @@ public MecaMind() { createMemoryGroup("Goal"); createMemoryGroup("Attention"); createMemoryGroup("Planning"); + createMemoryGroup("Working"); + for (String s : getWorkingMemory().getInternalMemoryNames()) { + registerMemory(getWorkingMemory().getInternalMemory(s),"Working"); + } } /** @@ -147,6 +151,10 @@ public MecaMind(String id) { createMemoryGroup("Goal"); createMemoryGroup("Attention"); createMemoryGroup("Planning"); + createMemoryGroup("Working"); + for (String s : getWorkingMemory().getInternalMemoryNames()) { + registerMemory(getWorkingMemory().getInternalMemory(s),"Working"); + } } /** @@ -473,7 +481,10 @@ private void mountAttentionCodelets() { /* * Outputs */ - Memory attentionMemoryOutput = createMemoryObject(attentionCodeletSystem1.getId()); + //Memory attentionMemoryOutput = createMemoryObject(attentionCodeletSystem1.getId()); + MemoryContainer currentperception = (MemoryContainer) workingMemory.getInternalMemory("CurrentPerceptionMemory"); + currentperception.setI(null,0d,attentionCodeletSystem1.getId()); + Memory attentionMemoryOutput = currentperception.getInternalMemory(attentionCodeletSystem1.getId()); attentionCodeletSystem1.addOutput(attentionMemoryOutput); attentionCodeletSystem1.setOutputFilteredPerceptsMO(attentionMemoryOutput); insertCodelet(attentionCodeletSystem1); @@ -502,8 +513,9 @@ private void mountGoalCodelets() { if (goalCodelets != null) { // Create the Goal Memory Container //MemoryContainer goalMemoryContainer = createMemoryContainer("OUTPUT_GOAL_MEMORY"); - MemoryContainer goalMemoryContainer = createMemoryContainer("Goals"); - registerMemory(goalMemoryContainer,"Goal"); + //MemoryContainer goalMemoryContainer = createMemoryContainer("Goals"); + //registerMemory(goalMemoryContainer,"Goal"); + MemoryContainer goalMemoryContainer = (MemoryContainer) workingMemory.getInternalMemory("GoalsMemory"); //MemoryObject wmem = createMemoryObject("INPUT_HYPOTHETICAL_SITUATIONS_MEMORY"); //registerMemory(wmem,"Goal"); //wmem.setI(workingMemory.getCurrentPerceptionMemory().getI()); @@ -524,6 +536,7 @@ private void mountGoalCodelets() { gc.addInput(workingMemory.getInternalMemory("CurrentPerceptionMemory")); //gc.addInput(wmem); // Mount output + gc.setGoalMO(goalMemoryContainer); goalMemoryContainer.setI(null,0.0,gc.getId()); gc.addOutput(goalMemoryContainer); diff --git a/src/main/java/br/unicamp/meca/system2/codelets/SoarCodelet.java b/src/main/java/br/unicamp/meca/system2/codelets/SoarCodelet.java index 4b137ae..a51d672 100644 --- a/src/main/java/br/unicamp/meca/system2/codelets/SoarCodelet.java +++ b/src/main/java/br/unicamp/meca/system2/codelets/SoarCodelet.java @@ -18,7 +18,6 @@ import java.util.List; import br.unicamp.cst.core.entities.Memory; -import br.unicamp.cst.motivational.Goal; import br.unicamp.cst.representation.wme.Idea; import br.unicamp.meca.memory.WorkingMemory; @@ -149,7 +148,7 @@ public void proc() { */ public Idea processWorkingMemoryInput() { - Idea il = new Idea("InputLink"); + Idea il = Idea.createIdea("InputLink","",0); //AbstractObject currentPerceptionWO = (AbstractObject) workingMemory.getCurrentPerceptionMemory().getI() != null Idea currentPerceptionWO = (Idea) workingMemory.getInternalMemory("CurrentPerceptionMemory").getI() != null @@ -164,8 +163,8 @@ public Idea processWorkingMemoryInput() { : null; //AbstractObject goalsWO = (List) workingMemory.getGoalsMemory().getI() != null - Idea goalsWO = (List) workingMemory.getInternalMemory("GoalsMemory").getI() != null - ? goalToIdea((List) workingMemory.getInternalMemory("GoalsMemory").getI()) : null; + Idea goalsWO = (List) workingMemory.getInternalMemory("GoalsMemory").getI() != null + ? goalToIdea((List) workingMemory.getInternalMemory("GoalsMemory").getI()) : null; //AbstractObject globalWO = (List) workingMemory.getGlobalWorkspaceMemory().getI() != null Idea globalWO = (List) workingMemory.getInternalMemory("GlobalWorkspaceMemory").getI() != null @@ -205,7 +204,7 @@ public Idea processWorkingMemoryInput() { */ public Idea convertToIdea(Idea abstractObject, String nodeName) { - Idea abs = new Idea(nodeName); + Idea abs = Idea.createIdea(nodeName,"",0); abs.add(abstractObject); @@ -223,7 +222,7 @@ public Idea convertToIdea(Idea abstractObject, String nodeName) { */ public Idea convertToIdea(List ideas, String nodeNameTemplate) { - Idea configs = new Idea(ideas.toString()); + Idea configs = Idea.createIdea(ideas.toString(),"",0); for (Idea abs : ideas) { configs.add(convertToIdea(abs, nodeNameTemplate)); @@ -238,15 +237,16 @@ public Idea convertToIdea(List ideas, String nodeNameTemplate) { * the list of goals. * @return the Abstract Object representing the Goals. */ - public Idea goalToIdea(List goals) { + public Idea goalToIdea(List goals) { - Idea go = new Idea("Goals"); + Idea go = Idea.createIdea("Goals","",0); - for (Goal goal : goals) { + for (Idea goal : goals) { - Idea temp = convertToIdea(goal.getGoalIdeas(), "GOAL"); - temp.add(new Idea(goal.getId())); - go.add(temp); + //Idea temp = convertToIdea(goal.getGoalIdeas(), "GOAL"); + //temp.add(new Idea(goal.getId())); + //go.add(temp); + go.add(goal); } return go; } @@ -284,7 +284,7 @@ public Idea globalWorkspaceToIdea(List global) { for (String st : globalStrings) { - gAbs.add(new Idea(st)); + gAbs.add(Idea.createIdea(st,"",0)); } return gAbs; From bf4ead046817a7cf7efd1c68c3ebc4b05e8256b8 Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Sun, 16 May 2021 19:57:47 -0300 Subject: [PATCH 45/89] trying to make jitpack work --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index ec94ca6..3fcacc4 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,7 @@ dependencies { //api group: "com.github.CST-Group", name: "cst", version: "codelet-tracking-SNAPSHOT", changing: true - api('com.github.CST-Group:cst:29b3611') + api('com.github.CST-Group:cst:55d7018') //api ':cst:0.6.2-full' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' From 73794893932f24af774e6d54c3dc36d94178e95c Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Sun, 16 May 2021 20:02:03 -0300 Subject: [PATCH 46/89] trying to make jitpack work --- build.gradle | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/build.gradle b/build.gradle index 3fcacc4..f731fc1 100644 --- a/build.gradle +++ b/build.gradle @@ -81,6 +81,14 @@ artifacts archives javadocJar, sourcesJar, uberJar } +publishing { + publications { + mavenJava(MavenPublication) { + from components.java + } + } +} + jacocoTestReport { reports { xml.enabled true From 4cd399851bb962a4c9d8027e929571025af86afd Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Sun, 16 May 2021 20:13:49 -0300 Subject: [PATCH 47/89] trying to make jitpack work --- build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index f731fc1..d542f30 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,8 @@ dependencies { //api group: "com.github.CST-Group", name: "cst", version: "codelet-tracking-SNAPSHOT", changing: true - api('com.github.CST-Group:cst:55d7018') + api('com.github.CST-Group:cst:241b3d3') + api 'org.ros.rosjava_messages:std_msgs:0.5.11' //api ':cst:0.6.2-full' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' From 434fb7a3a31410e529b1d279b3dc5be2e19edf1f Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Mon, 17 May 2021 19:05:44 -0300 Subject: [PATCH 48/89] Changes to make ortools to work --- build.gradle | 2 +- src/main/java/br/unicamp/meca/mind/MecaMind.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index d542f30..79e6adf 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,7 @@ dependencies { //api group: "com.github.CST-Group", name: "cst", version: "codelet-tracking-SNAPSHOT", changing: true - api('com.github.CST-Group:cst:241b3d3') + api('com.github.CST-Group:cst:f34cf9d') api 'org.ros.rosjava_messages:std_msgs:0.5.11' //api ':cst:0.6.2-full' testImplementation group: 'junit', name: 'junit', version: '4.12' diff --git a/src/main/java/br/unicamp/meca/mind/MecaMind.java b/src/main/java/br/unicamp/meca/mind/MecaMind.java index 5d8feb3..42e72ea 100644 --- a/src/main/java/br/unicamp/meca/mind/MecaMind.java +++ b/src/main/java/br/unicamp/meca/mind/MecaMind.java @@ -494,7 +494,8 @@ private void mountAttentionCodelets() { private void mountPlanningCodelet() { if (planningCodelet != null) { planningCodelet.addInput(createMemoryObject(WorkingMemory.WORKING_MEMORY_INPUT, getWorkingMemory())); - planningCodelet.addOutput(createMemoryObject(planningCodelet.getId())); + //planningCodelet.addOutput(createMemoryObject(planningCodelet.getId())); + planningCodelet.addOutput(getWorkingMemory().getInternalMemory("PlansMemory")); insertCodelet((Codelet) planningCodelet); } } From f1157a54f732afbcce031c266a5859ec8708e03a Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Mon, 17 May 2021 19:27:10 -0300 Subject: [PATCH 49/89] Changes to make jitpack to work --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 79e6adf..34c3f76 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,7 @@ dependencies { //api group: "com.github.CST-Group", name: "cst", version: "codelet-tracking-SNAPSHOT", changing: true - api('com.github.CST-Group:cst:f34cf9d') + api('com.github.CST-Group:cst:1d55d8c') api 'org.ros.rosjava_messages:std_msgs:0.5.11' //api ':cst:0.6.2-full' testImplementation group: 'junit', name: 'junit', version: '4.12' From 062c7c76f8af9db823731552f3c29d8fc013c402 Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Mon, 17 May 2021 19:39:17 -0300 Subject: [PATCH 50/89] Changes to make jitpack to work --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index 34c3f76..a405f6c 100644 --- a/build.gradle +++ b/build.gradle @@ -76,6 +76,7 @@ task uberJar(type: Jar) { from { configurations.runtimeClasspath.findAll { it.name.endsWith('jar') }.collect { zipTree(it) } } + exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA' } artifacts { From d16c5e975b9dc6a380782ce77649e0adf5591e34 Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Mon, 17 May 2021 22:48:26 -0300 Subject: [PATCH 51/89] Mounting an eventual ConsciousnessCodelet --- src/main/java/br/unicamp/meca/mind/MecaMind.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/br/unicamp/meca/mind/MecaMind.java b/src/main/java/br/unicamp/meca/mind/MecaMind.java index 42e72ea..6ca7181 100644 --- a/src/main/java/br/unicamp/meca/mind/MecaMind.java +++ b/src/main/java/br/unicamp/meca/mind/MecaMind.java @@ -143,6 +143,7 @@ public MecaMind(String id) { createCodeletGroup("Attention"); createCodeletGroup("Planning"); createCodeletGroup("Goal"); + createCodeletGroup("Consciousness"); createMemoryGroup("Sensors"); createMemoryGroup("Actuators"); createMemoryGroup("Percepts"); @@ -179,6 +180,7 @@ public void mountMecaMind() { mountActivityTrackingCodelet(); mountActivityCodelets(); mountGoalCodelets(); + mountConsciousnessCodelet(); mountModules(); mountMemoryGroups(); } @@ -546,6 +548,13 @@ private void mountGoalCodelets() { } } } + + private void mountConsciousnessCodelet() { + if (consciousnessCodelet != null) { + registerCodelet(consciousnessCodelet,"Consciousness"); + insertCodelet(consciousnessCodelet); + } + } /** * Sets the Sensory Codelets. From cdafd5dd90bdbb7e3d742be96dca1b1ad10e3481 Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Tue, 18 May 2021 09:08:56 -0300 Subject: [PATCH 52/89] Changes in the Idea registration mechanism in order to make its internal lists thread safe --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a405f6c..35993f1 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,7 @@ dependencies { //api group: "com.github.CST-Group", name: "cst", version: "codelet-tracking-SNAPSHOT", changing: true - api('com.github.CST-Group:cst:1d55d8c') + api('com.github.CST-Group:cst:6355910') api 'org.ros.rosjava_messages:std_msgs:0.5.11' //api ':cst:0.6.2-full' testImplementation group: 'junit', name: 'junit', version: '4.12' From 265651d1507a0595c8aaebd4e78048a8abb4ca87 Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Sun, 23 May 2021 18:28:53 -0300 Subject: [PATCH 53/89] Changes in ActionSequencePlan to solve a bug when the currentActionIndex is invalid --- src/main/java/br/unicamp/meca/models/ActionSequencePlan.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java b/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java index 483b97f..77ea078 100644 --- a/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java +++ b/src/main/java/br/unicamp/meca/models/ActionSequencePlan.java @@ -49,7 +49,9 @@ public ActionSequencePlan(ActionStep[] actionIdSequence) { * @return the current ActionStep */ public ActionStep getCurrentActionStep() { - return actionIdSequence[currentActionIdIndex]; + if (actionIdSequence != null && currentActionIdIndex < actionIdSequence.length) + return actionIdSequence[currentActionIdIndex]; + else return(null); } /** From e908bcc5f73c2347991773473975b23dbf1bd87c Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Sun, 23 May 2021 23:00:56 -0300 Subject: [PATCH 54/89] Commented lines on the Idea class to avoid too many messages --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 35993f1..66c2dea 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,7 @@ dependencies { //api group: "com.github.CST-Group", name: "cst", version: "codelet-tracking-SNAPSHOT", changing: true - api('com.github.CST-Group:cst:6355910') + api('com.github.CST-Group:cst:f777531') api 'org.ros.rosjava_messages:std_msgs:0.5.11' //api ':cst:0.6.2-full' testImplementation group: 'junit', name: 'junit', version: '4.12' From 43b2cc5b060ec5dc3187e9393e6b18ab50e3ca74 Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Thu, 27 May 2021 11:02:24 -0300 Subject: [PATCH 55/89] Created RosTopicOneShotPublisherCodelet in order to generate a ROS topic which is published only once (when changes are available) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 66c2dea..2216201 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,7 @@ dependencies { //api group: "com.github.CST-Group", name: "cst", version: "codelet-tracking-SNAPSHOT", changing: true - api('com.github.CST-Group:cst:f777531') + api('com.github.CST-Group:cst:20f5a38') api 'org.ros.rosjava_messages:std_msgs:0.5.11' //api ':cst:0.6.2-full' testImplementation group: 'junit', name: 'junit', version: '4.12' From a9da97c5dd5422f752e304780de2713420268e48 Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Thu, 27 May 2021 11:11:39 -0300 Subject: [PATCH 56/89] Created RosTopicOneShotPublisherMotorCodelet in order to generate a ROS topic which is published only once (when changes are available) --- .../RosTopicOneShotPublisherMotorCodelet.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/main/java/br/unicamp/meca/system1/codelets/RosTopicOneShotPublisherMotorCodelet.java diff --git a/src/main/java/br/unicamp/meca/system1/codelets/RosTopicOneShotPublisherMotorCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/RosTopicOneShotPublisherMotorCodelet.java new file mode 100644 index 0000000..2f9d27a --- /dev/null +++ b/src/main/java/br/unicamp/meca/system1/codelets/RosTopicOneShotPublisherMotorCodelet.java @@ -0,0 +1,54 @@ +/** + * + */ +package br.unicamp.meca.system1.codelets; + +import br.unicamp.cst.bindings.rosjava.RosTopicOneShotPublisherCodelet; +import java.net.URI; + + +/** + * A Wrapper of the CST's RosTopicPublisherCodelet implementing the IMotorCodelet interface, + * in order to be able to be mounted on the MecaMind. + * + * @author andre + * + * @param The ROS Message Type - Ex: std_msgs.String from ROS standard messages + */ +public abstract class RosTopicOneShotPublisherMotorCodelet extends RosTopicOneShotPublisherCodelet implements IMotorCodelet{ + + protected String id; + + /** + * Constructor for the RosTopicPublisherMotorCodelet. + * + * @param id the id of this Motor Codelet, to be used in mounting MECA Mind. Also the name of this ROS node. + * @param topic the name of the ROS topic this node will be publishing to. + * @param messageType the ROS message type. Ex: "std_msgs.String". + * @param host the host IP where to run. Ex: "127.0.0.1". + * @param masterURI the URI of the master ROS node. Ex: new URI("http://127.0.0.1:11311"). + */ + public RosTopicOneShotPublisherMotorCodelet(String id, String topic, String messageType, String host, URI masterURI) { + super(id, topic, messageType, host, masterURI); + this.id = id; + } + + /** + * Returns the id of this RosTopicPublisherMotorCodelet. + * + * @return the id + */ + public String getId() { + return id; + } + + /** + * Sets the id of this RosTopicPublisherMotorCodelet. + * + * @param id + * the id to set + */ + public void setId(String id) { + this.id = id; + } +} From 2a24fae037cd075232bfb306bcbcab814821768f Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Thu, 27 May 2021 11:56:01 -0300 Subject: [PATCH 57/89] Created RosTopicOneShotPublisherMotorCodelet in order to generate a ROS topic which is published only once (when changes are available) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 2216201..1dc448f 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,7 @@ dependencies { //api group: "com.github.CST-Group", name: "cst", version: "codelet-tracking-SNAPSHOT", changing: true - api('com.github.CST-Group:cst:20f5a38') + api('com.github.CST-Group:cst:78567d1') api 'org.ros.rosjava_messages:std_msgs:0.5.11' //api ':cst:0.6.2-full' testImplementation group: 'junit', name: 'junit', version: '4.12' From 31a81b6e3f3636228e0b7cbae701f7231f104ad6 Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Thu, 27 May 2021 19:02:20 -0300 Subject: [PATCH 58/89] Created RosTopicOneShotPublisherMotorCodelet in order to generate a ROS topic which is published only once (when changes are available) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 1dc448f..5f9cd46 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,7 @@ dependencies { //api group: "com.github.CST-Group", name: "cst", version: "codelet-tracking-SNAPSHOT", changing: true - api('com.github.CST-Group:cst:78567d1') + api('com.github.CST-Group:cst:23f2405') api 'org.ros.rosjava_messages:std_msgs:0.5.11' //api ':cst:0.6.2-full' testImplementation group: 'junit', name: 'junit', version: '4.12' From 68943aa19e12e268f3b367d4657c9da90c488ac9 Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Thu, 27 May 2021 23:53:35 -0300 Subject: [PATCH 59/89] Created RosTopicOneShotPublisherMotorCodelet in order to generate a ROS topic which is published only once (when changes are available) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 5f9cd46..5f7adeb 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,7 @@ dependencies { //api group: "com.github.CST-Group", name: "cst", version: "codelet-tracking-SNAPSHOT", changing: true - api('com.github.CST-Group:cst:23f2405') + api('com.github.CST-Group:cst:2461312') api 'org.ros.rosjava_messages:std_msgs:0.5.11' //api ':cst:0.6.2-full' testImplementation group: 'junit', name: 'junit', version: '4.12' From 1d4789dc223ab9ff1a5d98f4d7b5771f02d03e95 Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Fri, 28 May 2021 00:17:03 -0300 Subject: [PATCH 60/89] Many adaptations for P3DX --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 5f7adeb..def6d3d 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,7 @@ dependencies { //api group: "com.github.CST-Group", name: "cst", version: "codelet-tracking-SNAPSHOT", changing: true - api('com.github.CST-Group:cst:2461312') + api('com.github.CST-Group:cst:14d0972') api 'org.ros.rosjava_messages:std_msgs:0.5.11' //api ':cst:0.6.2-full' testImplementation group: 'junit', name: 'junit', version: '4.12' From ed0373a362de0a25913836c559c0b6163bfc9fbe Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Mon, 31 May 2021 22:19:51 -0300 Subject: [PATCH 61/89] Change in the name of ActionSequencePlanRequestMemoryContainer, to differentiate from the ActionSequencePlanMemoryContainer --- .../br/unicamp/meca/system1/codelets/BehaviorCodelet.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/br/unicamp/meca/system1/codelets/BehaviorCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/BehaviorCodelet.java index b7b9b9b..3728a80 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/BehaviorCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/BehaviorCodelet.java @@ -175,10 +175,10 @@ public void proc() { if(actionSequencePlan != null) { ((MemoryContainer) actionSequencePlanMemoryContainer).setI(actionSequencePlan,getActivation(),id); - ((MemoryContainer) actionSequencePlanRequestMemoryContainer).setI(null,0.0d,id); + ((MemoryContainer) actionSequencePlanRequestMemoryContainer).setI(null,0.0d,"R_"+id); }else { ((MemoryContainer) actionSequencePlanMemoryContainer).setI(null,0.0d,id); - ((MemoryContainer) actionSequencePlanRequestMemoryContainer).setI(id,getActivation(),id); + ((MemoryContainer) actionSequencePlanRequestMemoryContainer).setI(id,getActivation(),"R_"+id); } } From 128a8ad142cd7311c276f46c3a8c1d58cf9ef784 Mon Sep 17 00:00:00 2001 From: "Ricardo R. Gudwin" Date: Tue, 28 Sep 2021 15:52:36 -0300 Subject: [PATCH 62/89] Moved to CST 0.7.0, now using the Idea object as representation. --- README.md | 4 ++-- build.gradle | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d15ec2d..63d7a5b 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Note: This library is still under development, and some concepts or features mig ``` dependencies { ... - implementation 'com.github.CST-Group:meca:0.5.0' + implementation 'com.github.CST-Group:meca:0.6.0' } ``` @@ -53,7 +53,7 @@ Sometimes, the version number (tag) in this README gets out of date, as maintain com.github.CST-Group meca - 0.5.0 + 0.6.0 ``` diff --git a/build.gradle b/build.gradle index def6d3d..d2c3a43 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ description = "The Multipurpose Enhanced Cognitive Architecture (MECA)" sourceCompatibility = 1.8 targetCompatibility = 1.8 -version = '0.5.1' +version = '0.6.0' repositories { flatDir { @@ -30,10 +30,7 @@ repositories { } dependencies { - //api group: "com.github.CST-Group", name: "cst", version: "codelet-tracking-SNAPSHOT", changing: true - - - api('com.github.CST-Group:cst:14d0972') + api('com.github.CST-Group:cst:0.7.0') api 'org.ros.rosjava_messages:std_msgs:0.5.11' //api ':cst:0.6.2-full' testImplementation group: 'junit', name: 'junit', version: '4.12' From 03c28893538642ef83203ed782b08d42856b8178 Mon Sep 17 00:00:00 2001 From: Wandemberg Gibaut <8431951+wandgibaut@users.noreply.github.com> Date: Fri, 8 Oct 2021 10:21:26 -0300 Subject: [PATCH 63/89] Create java-ci.yml --- .github/workflows/java-ci.yml | 48 +++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 .github/workflows/java-ci.yml diff --git a/.github/workflows/java-ci.yml b/.github/workflows/java-ci.yml new file mode 100644 index 0000000..1915def --- /dev/null +++ b/.github/workflows/java-ci.yml @@ -0,0 +1,48 @@ +name: Java CI + +on: + # Trigger the workflow on push or pull request, + # but only for the main branch + push: + branches: + - master + pull_request: + branches: + - master + +jobs: + build: + runs-on: ubuntu-18.04 + strategy: + matrix: + java: [ '8', '11'] + name: JDK ${{ matrix.Java }} build + steps: + - uses: actions/checkout@v2 + - name: Set up Java + uses: actions/setup-java@v2 + with: + java-version: ${{ matrix.java }} + distribution: 'adopt' + cache: gradle + - name: Before Script + run: curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter && chmod +x ./cc-test-reporter && ./cc-test-reporter before-build + - name: Validate Gradle wrapper + uses: gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b + - name: Build with Gradle headless + uses: GabrielBB/xvfb-action@v1 + with: + run: ./gradlew clean build jacocoTestReport + - name: Cleanup Gradle Cache + # Remove some files from the Gradle cache, so they aren't cached by GitHub Actions. + # Restoring these files from a GitHub Actions cache might cause problems for future builds. + run: | + rm -f ~/.gradle/caches/modules-2/modules-2.lock + rm -f ~/.gradle/caches/modules-2/gc.properties + - name: Test & publish code coverage + uses: paambaati/codeclimate-action@v3.0.0 + env: + CC_TEST_REPORTER_ID: cd9dce60ab1686b279c6b871d4f5171e3dc3d17426617eb12db6cfee74da898c + JACOCO_SOURCE_PATH: "${{github.workspace}}/src/main/java" + with: + coverageLocations: ${{github.workspace}}/build/reports/jacoco/test/jacocoTestReport.xml:jacoco From 2ef9e5a59d0e13f43e179c9bbc795f7e93a37568 Mon Sep 17 00:00:00 2001 From: Wandemberg Gibaut <8431951+wandgibaut@users.noreply.github.com> Date: Fri, 8 Oct 2021 10:24:33 -0300 Subject: [PATCH 64/89] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 63d7a5b..d98e237 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -[![Build Status](https://travis-ci.org/CST-Group/meca.svg?branch=master)](https://travis-ci.org/CST-Group/meca) [![Maintainability](https://api.codeclimate.com/v1/badges/c24e46ebcdc9aa6a035e/maintainability)](https://codeclimate.com/github/CST-Group/meca/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/c24e46ebcdc9aa6a035e/test_coverage)](https://codeclimate.com/github/CST-Group/meca/test_coverage) +![](https://github.com/CST-Group/meca/actions/workflows/java-ci.yml/badge.svg) +[![Maintainability](https://api.codeclimate.com/v1/badges/c24e46ebcdc9aa6a035e/maintainability)](https://codeclimate.com/github/CST-Group/meca/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/c24e46ebcdc9aa6a035e/test_coverage)](https://codeclimate.com/github/CST-Group/meca/test_coverage) [![](https://jitpack.io/v/CST-Group/meca.svg?label=Release)](https://jitpack.io/#CST-Group/meca) # MECA From 34f0635d38213957085e49dd111162779ea392b0 Mon Sep 17 00:00:00 2001 From: Wandemberg Gibaut <8431951+wandgibaut@users.noreply.github.com> Date: Fri, 8 Oct 2021 10:24:44 -0300 Subject: [PATCH 65/89] Create README.md From ce590003ca252532292cd4d7ca1af2229b3c8daa Mon Sep 17 00:00:00 2001 From: Ricardo Gudwin Date: Wed, 26 Mar 2025 17:53:42 -0300 Subject: [PATCH 66/89] Upgrading to cst-desktop 1.1.0 --- build.gradle | 36 +++++++++++-------- gradle/wrapper/gradle-wrapper.properties | 2 +- .../java/br/unicamp/meca/mind/MecaMind.java | 8 ++++- .../system1/codelets/AttentionCodelet.java | 2 +- .../meca/system2/codelets/GoalCodelet.java | 2 +- .../meca/system2/codelets/SoarCodelet.java | 2 +- .../br/unicamp/meca/mind/MecaMindTest.java | 2 +- 7 files changed, 33 insertions(+), 21 deletions(-) diff --git a/build.gradle b/build.gradle index d2c3a43..c6e9ae3 100644 --- a/build.gradle +++ b/build.gradle @@ -18,19 +18,20 @@ repositories { } mavenCentral() maven { url 'https://jitpack.io' } - maven { - url "https://github.com/rosjava/rosjava_mvn_repo/raw/master" - } maven { - url "https://repository.springsource.com/maven/bundles/release" + url "https://github.com/rosjava/rosjava_mvn_repo/raw/master" } maven { - url "https://repository.springsource.com/maven/bundles/external" + url "https://artifacts.camunda.com/artifactory/public/" } } +configurations { + extraLibs +} + dependencies { - api('com.github.CST-Group:cst:0.7.0') + api('com.github.CST-Group:cst-desktop:1.1.0') api 'org.ros.rosjava_messages:std_msgs:0.5.11' //api ':cst:0.6.2-full' testImplementation group: 'junit', name: 'junit', version: '4.12' @@ -53,21 +54,25 @@ jar { } task javadocJar(type: Jar) { - classifier = 'javadoc' + archiveClassifier = 'javadoc' from javadoc + from { + configurations.extraLibs.collect { it.isDirectory() ? it : zipTree(it) } + } + javadoc.options.addStringOption('Xdoclint:none', '-quiet') // this is to avoid complaints about documentation missing parameter description } task sourcesJar(type: Jar) { - classifier = 'sources' + archiveClassifier = 'sources' from sourceSets.main.allSource + from { + configurations.extraLibs.collect { it.isDirectory() ? it : zipTree(it) } + } } + + task uberJar(type: Jar) { + duplicatesStrategy = DuplicatesStrategy.EXCLUDE archiveClassifier = 'full' - manifest { - attributes( - 'Class-Path': configurations.runtimeClasspath.files.collect { it.getName() }.join(' ') - ) - - } from sourceSets.main.output dependsOn configurations.runtimeClasspath from { @@ -75,6 +80,7 @@ task uberJar(type: Jar) { } exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA' } + artifacts { archives javadocJar, sourcesJar, uberJar @@ -90,6 +96,6 @@ publishing { jacocoTestReport { reports { - xml.enabled true + xml.required = true } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 622ab64..e1adfb4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/br/unicamp/meca/mind/MecaMind.java b/src/main/java/br/unicamp/meca/mind/MecaMind.java index 6ca7181..3edf1d3 100644 --- a/src/main/java/br/unicamp/meca/mind/MecaMind.java +++ b/src/main/java/br/unicamp/meca/mind/MecaMind.java @@ -24,6 +24,7 @@ import br.unicamp.cst.core.entities.MemoryContainer; import br.unicamp.cst.core.entities.MemoryObject; import br.unicamp.cst.core.entities.Mind; +import br.unicamp.cst.bindings.soar.PlansSubsystemModule; import br.unicamp.meca.memory.WorkingMemory; import br.unicamp.meca.system1.codelets.ActivityCodelet; import br.unicamp.meca.system1.codelets.ActivityTrackingCodelet; @@ -76,7 +77,8 @@ public class MecaMind extends Mind { private Memory actionSequencePlanMemoryContainer; private Memory actionSequencePlanRequestMemoryContainer; private ActivityTrackingCodelet activityTrackingCodelet; - private static HashMap memoryGroups = new HashMap(); + private static HashMap memoryGroups = new HashMap(); + private PlansSubsystemModule plansSubsystemModule = new PlansSubsystemModule(); /* * System 2 @@ -956,4 +958,8 @@ public void setActivityCodelets(List activityCodelets) { public void setPlanningCodelet(IPlanningCodelet planningCodelet) { this.planningCodelet = planningCodelet; } + + public PlansSubsystemModule getPlansSubsystemModule() { + return plansSubsystemModule; + } } diff --git a/src/main/java/br/unicamp/meca/system1/codelets/AttentionCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/AttentionCodelet.java index 2a6439e..c1d34ea 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/AttentionCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/AttentionCodelet.java @@ -18,7 +18,7 @@ import br.unicamp.cst.core.entities.Codelet; import br.unicamp.cst.core.entities.Memory; import br.unicamp.cst.core.exceptions.CodeletActivationBoundsException; -import br.unicamp.cst.representation.wme.Idea; +import br.unicamp.cst.representation.idea.Idea; /** * This class represents a MECA Attention Codelet in System 1. Attention diff --git a/src/main/java/br/unicamp/meca/system2/codelets/GoalCodelet.java b/src/main/java/br/unicamp/meca/system2/codelets/GoalCodelet.java index 19678e5..4bd6a7f 100644 --- a/src/main/java/br/unicamp/meca/system2/codelets/GoalCodelet.java +++ b/src/main/java/br/unicamp/meca/system2/codelets/GoalCodelet.java @@ -14,7 +14,7 @@ import br.unicamp.cst.core.entities.Memory; import br.unicamp.cst.core.entities.MemoryContainer; -import br.unicamp.cst.representation.wme.Idea; +import br.unicamp.cst.representation.idea.Idea; import br.unicamp.meca.memory.WorkingMemory; /** diff --git a/src/main/java/br/unicamp/meca/system2/codelets/SoarCodelet.java b/src/main/java/br/unicamp/meca/system2/codelets/SoarCodelet.java index a51d672..7907250 100644 --- a/src/main/java/br/unicamp/meca/system2/codelets/SoarCodelet.java +++ b/src/main/java/br/unicamp/meca/system2/codelets/SoarCodelet.java @@ -18,7 +18,7 @@ import java.util.List; import br.unicamp.cst.core.entities.Memory; -import br.unicamp.cst.representation.wme.Idea; +import br.unicamp.cst.representation.idea.Idea; import br.unicamp.meca.memory.WorkingMemory; /** diff --git a/src/test/java/br/unicamp/meca/mind/MecaMindTest.java b/src/test/java/br/unicamp/meca/mind/MecaMindTest.java index 1db9b98..2662225 100644 --- a/src/test/java/br/unicamp/meca/mind/MecaMindTest.java +++ b/src/test/java/br/unicamp/meca/mind/MecaMindTest.java @@ -17,7 +17,7 @@ import br.unicamp.cst.core.entities.Memory; import br.unicamp.cst.core.entities.MemoryContainer; import br.unicamp.cst.core.exceptions.CodeletActivationBoundsException; -import br.unicamp.cst.util.MindViewer; +import br.unicamp.cst.util.viewer.MindViewer; import br.unicamp.meca.mind.action.Test1ActivityCodelet; import br.unicamp.meca.mind.action.Test2ActivityCodelet; import br.unicamp.meca.mind.action.Test3ActivityCodelet; From 187a6b7f16cdb3e9d185f73ef20b6b97768fa805 Mon Sep 17 00:00:00 2001 From: Ricardo Gudwin Date: Wed, 26 Mar 2025 18:03:42 -0300 Subject: [PATCH 67/89] Fixing README.md --- README.md | 4 ++-- build.gradle | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d98e237..033989f 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Note: This library is still under development, and some concepts or features mig ``` dependencies { ... - implementation 'com.github.CST-Group:meca:0.6.0' + implementation 'com.github.CST-Group:meca:0.7.0' } ``` @@ -54,7 +54,7 @@ Sometimes, the version number (tag) in this README gets out of date, as maintain com.github.CST-Group meca - 0.6.0 + 0.7.0 ``` diff --git a/build.gradle b/build.gradle index c6e9ae3..37a1ae2 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ description = "The Multipurpose Enhanced Cognitive Architecture (MECA)" sourceCompatibility = 1.8 targetCompatibility = 1.8 -version = '0.6.0' +version = '0.7.0' repositories { flatDir { @@ -33,7 +33,6 @@ configurations { dependencies { api('com.github.CST-Group:cst-desktop:1.1.0') api 'org.ros.rosjava_messages:std_msgs:0.5.11' - //api ':cst:0.6.2-full' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' testImplementation 'org.ros.rosjava_messages:rosjava_test_msgs:0.3.0' From 9d7e743cb4af465b76da1dd700014c5700e2458f Mon Sep 17 00:00:00 2001 From: Ricardo Ribeiro Gudwin Date: Wed, 26 Mar 2025 18:24:59 -0300 Subject: [PATCH 68/89] Update java-ci.yml --- .github/workflows/java-ci.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/java-ci.yml b/.github/workflows/java-ci.yml index 1915def..b1af0f7 100644 --- a/.github/workflows/java-ci.yml +++ b/.github/workflows/java-ci.yml @@ -12,15 +12,15 @@ on: jobs: build: - runs-on: ubuntu-18.04 + runs-on: ubuntu-22.04 strategy: matrix: - java: [ '8', '11'] + java: [ '8', '11', '17', '21'] name: JDK ${{ matrix.Java }} build steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4.1.1 - name: Set up Java - uses: actions/setup-java@v2 + uses: actions/setup-java@v4.2.1 with: java-version: ${{ matrix.java }} distribution: 'adopt' @@ -28,9 +28,9 @@ jobs: - name: Before Script run: curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter && chmod +x ./cc-test-reporter && ./cc-test-reporter before-build - name: Validate Gradle wrapper - uses: gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b + uses: gradle/wrapper-validation-action@v3.3.0 - name: Build with Gradle headless - uses: GabrielBB/xvfb-action@v1 + uses: coactions/setup-xvfb@v1.0.1 with: run: ./gradlew clean build jacocoTestReport - name: Cleanup Gradle Cache @@ -40,7 +40,7 @@ jobs: rm -f ~/.gradle/caches/modules-2/modules-2.lock rm -f ~/.gradle/caches/modules-2/gc.properties - name: Test & publish code coverage - uses: paambaati/codeclimate-action@v3.0.0 + uses: paambaati/codeclimate-action@v5.0.0 env: CC_TEST_REPORTER_ID: cd9dce60ab1686b279c6b871d4f5171e3dc3d17426617eb12db6cfee74da898c JACOCO_SOURCE_PATH: "${{github.workspace}}/src/main/java" From 734c345dcabbb2a8f669f648e285f34e124ef58d Mon Sep 17 00:00:00 2001 From: rgudwin Date: Thu, 11 Sep 2025 16:24:38 -0300 Subject: [PATCH 69/89] Updating to gradle 8.14.3 --- build.gradle | 7 ++++--- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 37a1ae2..c3b4ede 100644 --- a/build.gradle +++ b/build.gradle @@ -17,12 +17,13 @@ repositories { dirs '../cst/build/libs' } mavenCentral() - maven { url 'https://jitpack.io' } + maven { url = 'https://jitpack.io' } maven { - url "https://github.com/rosjava/rosjava_mvn_repo/raw/master" + url = "https://github.com/rosjava/rosjava_mvn_repo/raw/master" } maven { - url "https://artifacts.camunda.com/artifactory/public/" + url = 'https://cst-group.github.io/cst-dependencies/maven-repo/' + } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e1adfb4..3ae1e2f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From ef3949d6f47ce5d86f1f1fa3649877d60734c268 Mon Sep 17 00:00:00 2001 From: Ricardo Ribeiro Gudwin Date: Thu, 11 Sep 2025 16:37:34 -0300 Subject: [PATCH 70/89] Update java-ci.yml --- .github/workflows/java-ci.yml | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/.github/workflows/java-ci.yml b/.github/workflows/java-ci.yml index b1af0f7..bc7da95 100644 --- a/.github/workflows/java-ci.yml +++ b/.github/workflows/java-ci.yml @@ -12,23 +12,21 @@ on: jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: matrix: java: [ '8', '11', '17', '21'] name: JDK ${{ matrix.Java }} build steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v5.0.0 - name: Set up Java - uses: actions/setup-java@v4.2.1 + uses: actions/setup-java@v5.0.0 with: java-version: ${{ matrix.java }} distribution: 'adopt' cache: gradle - - name: Before Script - run: curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter && chmod +x ./cc-test-reporter && ./cc-test-reporter before-build - name: Validate Gradle wrapper - uses: gradle/wrapper-validation-action@v3.3.0 + uses: gradle/action/wrapper-validation@v4.4.2 - name: Build with Gradle headless uses: coactions/setup-xvfb@v1.0.1 with: @@ -40,9 +38,8 @@ jobs: rm -f ~/.gradle/caches/modules-2/modules-2.lock rm -f ~/.gradle/caches/modules-2/gc.properties - name: Test & publish code coverage - uses: paambaati/codeclimate-action@v5.0.0 - env: - CC_TEST_REPORTER_ID: cd9dce60ab1686b279c6b871d4f5171e3dc3d17426617eb12db6cfee74da898c - JACOCO_SOURCE_PATH: "${{github.workspace}}/src/main/java" + uses: qltysh/qlty-action/coverage@v2 with: - coverageLocations: ${{github.workspace}}/build/reports/jacoco/test/jacocoTestReport.xml:jacoco + oidc: true + files: ${{github.workspace}}/build/reports/jacoco/test/jacocoTestReport.xml + add-prefix: src/main/java/ From 7d74ef141e22840d9e5dcf48b7308bf908d89f94 Mon Sep 17 00:00:00 2001 From: Ricardo Ribeiro Gudwin Date: Thu, 11 Sep 2025 16:40:10 -0300 Subject: [PATCH 71/89] Update .travis.yml --- .travis.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1acf57b..698ff05 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,15 +8,10 @@ services: jdk: - openjdk8 - openjdk9 -before_script: - - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter - - chmod +x ./cc-test-reporter - - ./cc-test-reporter before-build script: - ./gradlew clean build jacocoTestReport after_script: - JACOCO_SOURCE_PATH=src/main/java ./cc-test-reporter format-coverage ./build/reports/jacoco/test/jacocoTestReport.xml --input-type jacoco - - ./cc-test-reporter upload-coverage -r $CC_TEST_REPORTER_ID -notifications: + notifications: slack: secure: jSd9irNrMQ8TtXW9H7yl3qGlQXA5Zp6mzGtM5OONofL3x3DOdvIkBb75+S7zZiQJn7QdVzNrGnb6pVm/r6wGUupyRr2HvHlS3s19qwrCDwl6+vW46AGS6ZgdiqhGSdV5yQkhRRoxRlLpHOq+9KnZ4Sycr74VV6Kk9EzBFmdfCPOVi7+iQWKJHYm/AUNIKfFk8OR4vpitwAqEgYguMHKyhh7Edv4pNHzExRlL8p6jdkGL7Ul5UF1q44AQdVsSGY0ByudJJNiU1AxjfLYaCWiBpvlYMJz/rY8Q023dw/EdEfAcg5evzZnljcLiBmRc4Y3lVyQvzffGoHwsXPWiKac7ZhtJ+tD1Hl+UG/IQtkEp814Iule1e/cUqgZ3jlNZI++lfKLUdadXHeDP5bdIOj1XGLf3T68Z3lmLJkFaVsPElxGmMM+3Pi1R2gTufH8FFW+njZR1FpEqZHtHpTt0QYEP+jL1hFH5Xo4jRPoexfEOe1oe3n61QR1c0YjPtdkpHif1oRMpruD7evq8KhAFJNqMe/K3KRTK8hoKT8arl/lqU0NRonCR1gaNHPjyvyPZfnya+PtijpL1zFJcRtEV6rDlmnQ9xxHcT8yCBHgIB2N2oU0qZlz/oy2Lx53chzeH55o+ypQ9Fcx4ra2riGlOkTGRX2WrcOBi2CmA/DEiWPpF8RM= From 0cbd802f671015735e047935d07896e464ede5c4 Mon Sep 17 00:00:00 2001 From: Ricardo Ribeiro Gudwin Date: Thu, 11 Sep 2025 16:45:08 -0300 Subject: [PATCH 72/89] Update java-ci.yml --- .github/workflows/java-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/java-ci.yml b/.github/workflows/java-ci.yml index bc7da95..a2fee43 100644 --- a/.github/workflows/java-ci.yml +++ b/.github/workflows/java-ci.yml @@ -26,7 +26,7 @@ jobs: distribution: 'adopt' cache: gradle - name: Validate Gradle wrapper - uses: gradle/action/wrapper-validation@v4.4.2 + uses: gradle/actions/wrapper-validation@v4.4.2 - name: Build with Gradle headless uses: coactions/setup-xvfb@v1.0.1 with: From a544fddaf760ef213a1ad5bfcef12a9f22229a76 Mon Sep 17 00:00:00 2001 From: rgudwin Date: Thu, 11 Sep 2025 16:54:43 -0300 Subject: [PATCH 73/89] Updating wrapper --- gradle/wrapper/gradle-wrapper.jar | Bin 55190 -> 43764 bytes gradle/wrapper/gradle-wrapper.properties | 2 + gradlew | 305 ++++++++++++++--------- gradlew.bat | 80 +++--- 4 files changed, 239 insertions(+), 148 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 87b738cbd051603d91cc39de6cb000dd98fe6b02..1b33c55baabb587c669f562ae36f953de2481846 100644 GIT binary patch literal 43764 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 z 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 \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m"' +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar +CLASSPATH="\\\"\\\"" + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -81,92 +132,120 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=$((i+1)) + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" fi +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 0f8d593..5eed7ee 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,4 +1,22 @@ -@if "%DEBUG%" == "" @echo off +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -9,25 +27,29 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -35,48 +57,36 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar +set CLASSPATH= + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal From ba05c9243e0cb14003e6d0bec5320bfdb07e9e59 Mon Sep 17 00:00:00 2001 From: rgudwin Date: Thu, 11 Sep 2025 17:00:03 -0300 Subject: [PATCH 74/89] inserting sleep before using ROSCore --- .../meca/system1/codelets/rosservice/RosServiceClientTest.java | 1 + .../codelets/rostopic/RosTopicPublisherSubscriberTest.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/RosServiceClientTest.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/RosServiceClientTest.java index a6bd043..1ab9d96 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/RosServiceClientTest.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/RosServiceClientTest.java @@ -34,6 +34,7 @@ public class RosServiceClientTest { public static void beforeAllTestMethods() { rosCore = RosCore.newPublic("127.0.0.1",11311); rosCore.start(); + try{Thread.sleep(1000);} catch(Exception e){e.printStackTrace();} } @AfterClass diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rostopic/RosTopicPublisherSubscriberTest.java b/src/test/java/br/unicamp/meca/system1/codelets/rostopic/RosTopicPublisherSubscriberTest.java index 5c0cb83..731154f 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rostopic/RosTopicPublisherSubscriberTest.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rostopic/RosTopicPublisherSubscriberTest.java @@ -32,6 +32,7 @@ public class RosTopicPublisherSubscriberTest { public static void beforeAllTestMethods() { rosCore = RosCore.newPublic("127.0.0.1",11311); rosCore.start(); + try{Thread.sleep(1000);} catch(Exception e){e.printStackTrace();} } @AfterClass From 1fe795fd544ae0ecdd817f75e06655a5dccaa6b0 Mon Sep 17 00:00:00 2001 From: Ricardo Ribeiro Gudwin Date: Thu, 11 Sep 2025 17:21:21 -0300 Subject: [PATCH 75/89] Update java-ci.yml --- .github/workflows/java-ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/java-ci.yml b/.github/workflows/java-ci.yml index a2fee43..f813a27 100644 --- a/.github/workflows/java-ci.yml +++ b/.github/workflows/java-ci.yml @@ -13,6 +13,10 @@ on: jobs: build: runs-on: ubuntu-24.04 + permissions: + contents: write + pages: write + id-token: write strategy: matrix: java: [ '8', '11', '17', '21'] From 7bdcf80e65b379461f0203ca12e0ef847f764d39 Mon Sep 17 00:00:00 2001 From: rgudwin Date: Thu, 18 Sep 2025 13:58:09 -0300 Subject: [PATCH 76/89] Trying to solve a Thread bug ... still with problems --- build.gradle | 10 ++- .../java/br/unicamp/meca/mind/MecaMind.java | 2 +- .../meca/system1/codelets/MotorCodelet.java | 2 +- .../rosservice/AddTwoIntServiceClient.java | 34 ++++++++- .../rosservice/RosServiceClientTest.java | 74 +++++++++++++++---- 5 files changed, 97 insertions(+), 25 deletions(-) diff --git a/build.gradle b/build.gradle index c3b4ede..396568f 100644 --- a/build.gradle +++ b/build.gradle @@ -14,7 +14,7 @@ version = '0.7.0' repositories { flatDir { - dirs '../cst/build/libs' + dirs '../cst-desktop/build/libs' } mavenCentral() maven { url = 'https://jitpack.io' } @@ -23,7 +23,6 @@ repositories { } maven { url = 'https://cst-group.github.io/cst-dependencies/maven-repo/' - } } @@ -32,7 +31,8 @@ configurations { } dependencies { - api('com.github.CST-Group:cst-desktop:1.1.0') + //api('com.github.CST-Group:cst-desktop:1.1.0') + api(':cst-desktop:1.1.1-full') api 'org.ros.rosjava_messages:std_msgs:0.5.11' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' @@ -99,3 +99,7 @@ jacocoTestReport { xml.required = true } } + +test { + maxParallelForks = 1 +} diff --git a/src/main/java/br/unicamp/meca/mind/MecaMind.java b/src/main/java/br/unicamp/meca/mind/MecaMind.java index 3edf1d3..fb0b983 100644 --- a/src/main/java/br/unicamp/meca/mind/MecaMind.java +++ b/src/main/java/br/unicamp/meca/mind/MecaMind.java @@ -73,7 +73,7 @@ public class MecaMind extends Mind { private List emotionalCodelets; private List activityCodelets; private List behaviorCodelets; - private List motorCodelets; + private volatile List motorCodelets; private Memory actionSequencePlanMemoryContainer; private Memory actionSequencePlanRequestMemoryContainer; private ActivityTrackingCodelet activityTrackingCodelet; diff --git a/src/main/java/br/unicamp/meca/system1/codelets/MotorCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/MotorCodelet.java index c92f7e3..a22d794 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/MotorCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/MotorCodelet.java @@ -34,7 +34,7 @@ public abstract class MotorCodelet extends Codelet implements IMotorCodelet{ protected String id; - protected Memory motorMemory; + protected volatile Memory motorMemory; /** * Creates a MECA Motor Codelet. diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntServiceClient.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntServiceClient.java index 732457e..c9607af 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntServiceClient.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntServiceClient.java @@ -6,6 +6,7 @@ import java.net.URI; import br.unicamp.cst.core.entities.Memory; +import br.unicamp.cst.support.TimeStamp; import br.unicamp.meca.system1.codelets.RosServiceClientMotorCodelet; import rosjava_test_msgs.AddTwoIntsRequest; import rosjava_test_msgs.AddTwoIntsResponse; @@ -16,7 +17,9 @@ */ public class AddTwoIntServiceClient extends RosServiceClientMotorCodelet { - private Integer sum; + private volatile Integer a,b; + private volatile Integer sum; + private volatile long tsreq=0, tsresp=0; public AddTwoIntServiceClient(String host, URI masterURI) { super("AddTwoIntServiceClient", "add_two_ints", rosjava_test_msgs.AddTwoInts._TYPE, host, masterURI); @@ -29,23 +32,46 @@ public boolean formatServiceRequest(Memory motorMemory, AddTwoIntsRequest servic } Integer[] numsToSum = (Integer[]) motorMemory.getI(); + a = numsToSum[0]; + b = numsToSum[1]; serviceMessageRequest.setA(numsToSum[0]); serviceMessageRequest.setB(numsToSum[1]); - + //tsreq = motorMemory.getTimestamp(); + tsreq = System.currentTimeMillis(); + //System.out.println("a = "+a+" b = "+b+" at "+TimeStamp.now()+" "+TimeStamp.getStringTimeStamp(tsreq)); + System.out.println("REQUEST a = "+a+" b = "+b+" at "+TimeStamp.getStringTimeStamp(tsreq)+" with data from "+TimeStamp.getStringTimeStamp(motorMemory.getTimestamp())); + return true; } @Override public void processServiceResponse(AddTwoIntsResponse serviceMessageResponse) { sum = (int) serviceMessageResponse.getSum(); - System.out.println("Sum = "+sum); + tsresp = System.currentTimeMillis(); + System.out.println("RESPONSE Sum = "+sum+" at "+TimeStamp.getStringTimeStamp(tsresp)); } /** * @return the sum */ - public Integer getSum() { + public synchronized Integer getSum() { return sum; } + + /** + * + * @return timestamp + */ + public synchronized long getTSReq() { + return tsreq; + } + + /** + * + * @return timestamp + */ + public synchronized long getTSResp() { + return tsresp; + } } diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/RosServiceClientTest.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/RosServiceClientTest.java index 1ab9d96..0d73574 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/RosServiceClientTest.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/RosServiceClientTest.java @@ -19,8 +19,12 @@ import org.ros.node.NodeMainExecutor; import br.unicamp.cst.core.entities.Memory; +import br.unicamp.cst.support.TimeStamp; import br.unicamp.meca.mind.MecaMind; import br.unicamp.meca.system1.codelets.IMotorCodelet; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.slf4j.LoggerFactory; /** * @author andre @@ -29,6 +33,7 @@ public class RosServiceClientTest { private static RosCore rosCore; + private volatile Memory motorMemory; @BeforeClass public static void beforeAllTestMethods() { @@ -42,6 +47,13 @@ public static void afterAllTestMethods() { rosCore.shutdown(); } + public void SilenceLoggers() { + ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger("httpclient")).setLevel(ch.qos.logback.classic.Level.OFF); + ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger("org.apache")).setLevel(ch.qos.logback.classic.Level.OFF); + ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger("org.ros")).setLevel(ch.qos.logback.classic.Level.OFF); + Logger.getLogger("Simulation").setLevel(Level.SEVERE); + } + @Test public void testRosService() throws URISyntaxException, InterruptedException { @@ -49,6 +61,7 @@ public void testRosService() throws URISyntaxException, InterruptedException { NodeMainExecutor nodeMainExecutor = DefaultNodeMainExecutor.newDefault(); NodeConfiguration nodeConfiguration = NodeConfiguration.newPublic("127.0.0.1",new URI("http://127.0.0.1:11311")); nodeMainExecutor.execute(addTwoIntService, nodeConfiguration); + Thread.sleep(2000); @@ -60,19 +73,18 @@ public void testRosService() throws URISyntaxException, InterruptedException { motorCodelets.add(addTwoIntServiceClient); mecaMind.setIMotorCodelets(motorCodelets); - - mecaMind.mountMecaMind(); - + mecaMind.mountMecaMind(); mecaMind.start(); Thread.sleep(5000); - Memory motorMemory = addTwoIntServiceClient.getInput(addTwoIntServiceClient.getId()); + motorMemory = addTwoIntServiceClient.getInput(addTwoIntServiceClient.getId()); Integer expectedSum = 5; Integer[] numsToSum = new Integer[] {2,3}; motorMemory.setI(numsToSum); + System.out.println("Nums to sum were changed to {2,3}"); Thread.sleep(2000); @@ -87,7 +99,8 @@ public void testRosService() throws URISyntaxException, InterruptedException { @Test public void testRosServiceCallTwice() throws URISyntaxException, InterruptedException { - AddTwoIntService addTwoIntService = new AddTwoIntService(); + SilenceLoggers(); + AddTwoIntService addTwoIntService = new AddTwoIntService(); NodeMainExecutor nodeMainExecutor = DefaultNodeMainExecutor.newDefault(); NodeConfiguration nodeConfiguration = NodeConfiguration.newPublic("127.0.0.1",new URI("http://127.0.0.1:11311")); nodeMainExecutor.execute(addTwoIntService, nodeConfiguration); @@ -102,32 +115,61 @@ public void testRosServiceCallTwice() throws URISyntaxException, InterruptedExce motorCodelets.add(addTwoIntServiceClient); mecaMind.setIMotorCodelets(motorCodelets); - - mecaMind.mountMecaMind(); - + mecaMind.mountMecaMind(); mecaMind.start(); Thread.sleep(5000); - Memory motorMemory = addTwoIntServiceClient.getInput(addTwoIntServiceClient.getId()); + synchronized(motorMemory) { + motorMemory = addTwoIntServiceClient.getInput(addTwoIntServiceClient.getId()); + } Integer expectedSum = 5; Integer[] numsToSum = new Integer[] {2,3}; motorMemory.setI(numsToSum); - - Thread.sleep(2000); + System.out.println("\n\nNums to sum were changed to {2,3} at "+TimeStamp.getStringTimeStamp(motorMemory.getTimestamp())); + long tsstartreq = addTwoIntServiceClient.getTSReq(); + long tsstopreq = tsstartreq; + long tsstartresp = addTwoIntServiceClient.getTSResp(); + long tsstopresp = tsstartresp; + System.out.println("Service situation - req:"+TimeStamp.getStringTimeStamp(tsstartreq)+" resp:"+TimeStamp.getStringTimeStamp(tsstartresp)); + while (tsstartreq == tsstopreq || tsstartresp == tsstopresp ) { + tsstopresp = addTwoIntServiceClient.getTSResp(); + tsstopreq = addTwoIntServiceClient.getTSReq(); + System.out.println("startreq: "+TimeStamp.getStringTimeStamp(tsstartreq)+" stopreq: "+TimeStamp.getStringTimeStamp(tsstopreq)); + System.out.println("startresp: "+TimeStamp.getStringTimeStamp(tsstartresp)+" stopreq: "+TimeStamp.getStringTimeStamp(tsstopresp)); + Thread.sleep(100); + } + System.out.println("Finished process - req:"+TimeStamp.getStringTimeStamp(tsstopreq)+" resp"+TimeStamp.getStringTimeStamp(tsstopresp)); + //Thread.sleep(5000); assertEquals(expectedSum, addTwoIntServiceClient.getSum()); expectedSum = 6; numsToSum = new Integer[] {3,3}; - motorMemory.setI(numsToSum); - - Thread.sleep(2000); - - assertEquals(expectedSum, addTwoIntServiceClient.getSum()); + //numsToSum[0] = 3; + //numsToSum[1] = 3; + synchronized(motorMemory) { + motorMemory.setI(numsToSum); + } + System.out.println("\n\nNums to sum were changed to {3,3} at "+TimeStamp.getStringTimeStamp(motorMemory.getTimestamp())); + tsstartreq = addTwoIntServiceClient.getTSReq(); + tsstopreq = tsstartreq; + tsstartresp = addTwoIntServiceClient.getTSResp(); + tsstopresp = tsstartresp; + System.out.println("Service situation - req:"+TimeStamp.getStringTimeStamp(tsstartreq)+" resp:"+TimeStamp.getStringTimeStamp(tsstartresp)); + while (tsstartreq == tsstopreq || tsstartresp == tsstopresp ) { + tsstopresp = addTwoIntServiceClient.getTSResp(); + tsstopreq = addTwoIntServiceClient.getTSReq(); + System.out.println("tsstartreq: "+TimeStamp.getStringTimeStamp(tsstartreq)+" tsstopreq: "+TimeStamp.getStringTimeStamp(tsstopreq)); + System.out.println("tsstartresp: "+TimeStamp.getStringTimeStamp(tsstartresp)+" tsstopreq: "+TimeStamp.getStringTimeStamp(tsstopresp)); + System.out.println("motorMemory: "+TimeStamp.getStringTimeStamp(motorMemory.getTimestamp())); + Thread.sleep(100); + } + System.out.println("Finished process - req:"+TimeStamp.getStringTimeStamp(tsstopreq)+" resp"+TimeStamp.getStringTimeStamp(tsstopresp)); + assertEquals(expectedSum, addTwoIntServiceClient.getSum()); nodeMainExecutor.shutdownNodeMain(addTwoIntService); From feb8dc6a47521ea25c2a2a4f73d0065be4184261 Mon Sep 17 00:00:00 2001 From: rgudwin Date: Thu, 18 Sep 2025 15:02:31 -0300 Subject: [PATCH 77/89] Solving the Thread problem ... which was instead a Container problem --- build.gradle | 4 +-- .../rosservice/AddTwoIntServiceClient.java | 2 -- .../rosservice/RosServiceClientTest.java | 25 ++++++++++--------- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/build.gradle b/build.gradle index 396568f..cec80c5 100644 --- a/build.gradle +++ b/build.gradle @@ -31,8 +31,8 @@ configurations { } dependencies { - //api('com.github.CST-Group:cst-desktop:1.1.0') - api(':cst-desktop:1.1.1-full') + api('com.github.CST-Group:cst-desktop:1.1.0') + // This if for debug purposes api(':cst-desktop:1.1.1-full') api 'org.ros.rosjava_messages:std_msgs:0.5.11' testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntServiceClient.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntServiceClient.java index c9607af..088826c 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntServiceClient.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntServiceClient.java @@ -36,9 +36,7 @@ public boolean formatServiceRequest(Memory motorMemory, AddTwoIntsRequest servic b = numsToSum[1]; serviceMessageRequest.setA(numsToSum[0]); serviceMessageRequest.setB(numsToSum[1]); - //tsreq = motorMemory.getTimestamp(); tsreq = System.currentTimeMillis(); - //System.out.println("a = "+a+" b = "+b+" at "+TimeStamp.now()+" "+TimeStamp.getStringTimeStamp(tsreq)); System.out.println("REQUEST a = "+a+" b = "+b+" at "+TimeStamp.getStringTimeStamp(tsreq)+" with data from "+TimeStamp.getStringTimeStamp(motorMemory.getTimestamp())); return true; diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/RosServiceClientTest.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/RosServiceClientTest.java index 0d73574..363326a 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/RosServiceClientTest.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/RosServiceClientTest.java @@ -19,6 +19,7 @@ import org.ros.node.NodeMainExecutor; import br.unicamp.cst.core.entities.Memory; +import br.unicamp.cst.core.entities.MemoryContainer; import br.unicamp.cst.support.TimeStamp; import br.unicamp.meca.mind.MecaMind; import br.unicamp.meca.system1.codelets.IMotorCodelet; @@ -120,14 +121,17 @@ public void testRosServiceCallTwice() throws URISyntaxException, InterruptedExce Thread.sleep(5000); - synchronized(motorMemory) { - motorMemory = addTwoIntServiceClient.getInput(addTwoIntServiceClient.getId()); - } - - Integer expectedSum = 5; + MemoryContainer mc=null; + motorMemory = addTwoIntServiceClient.getInput(addTwoIntServiceClient.getId()); + // Be careful ... at this point motorMemory is a MemoryContainer, and it is empty + if (motorMemory instanceof MemoryContainer) + mc = (MemoryContainer) motorMemory; + Integer expectedSum = 5; Integer[] numsToSum = new Integer[] {2,3}; - motorMemory.setI(numsToSum); + int id = motorMemory.setI(numsToSum); + // At this point, motorMemory has 1 internal MemoryObject and id should be 0 + System.out.println("id: "+id); System.out.println("\n\nNums to sum were changed to {2,3} at "+TimeStamp.getStringTimeStamp(motorMemory.getTimestamp())); long tsstartreq = addTwoIntServiceClient.getTSReq(); long tsstopreq = tsstartreq; @@ -141,7 +145,7 @@ public void testRosServiceCallTwice() throws URISyntaxException, InterruptedExce System.out.println("startresp: "+TimeStamp.getStringTimeStamp(tsstartresp)+" stopreq: "+TimeStamp.getStringTimeStamp(tsstopresp)); Thread.sleep(100); } - System.out.println("Finished process - req:"+TimeStamp.getStringTimeStamp(tsstopreq)+" resp"+TimeStamp.getStringTimeStamp(tsstopresp)); + System.out.println("Finished process - req:"+TimeStamp.getStringTimeStamp(tsstopreq)+" resp:"+TimeStamp.getStringTimeStamp(tsstopresp)); //Thread.sleep(5000); assertEquals(expectedSum, addTwoIntServiceClient.getSum()); @@ -149,11 +153,8 @@ public void testRosServiceCallTwice() throws URISyntaxException, InterruptedExce expectedSum = 6; numsToSum = new Integer[] {3,3}; - //numsToSum[0] = 3; - //numsToSum[1] = 3; - synchronized(motorMemory) { - motorMemory.setI(numsToSum); - } + // This is the tricker part ... instead of calling setI from motorMemory, we should use its MemoryContainer counterpart + mc.setI(numsToSum,0); System.out.println("\n\nNums to sum were changed to {3,3} at "+TimeStamp.getStringTimeStamp(motorMemory.getTimestamp())); tsstartreq = addTwoIntServiceClient.getTSReq(); tsstopreq = tsstartreq; From 751d0301f95d294d81b831f8a97d5d185aa94d2f Mon Sep 17 00:00:00 2001 From: Jose Renato Borelli Date: Mon, 29 Sep 2025 02:06:09 -0300 Subject: [PATCH 78/89] meca - ROS2 - to be fixed --- build.gradle | 88 ++++++++----- settings.gradle | 3 +- .../Ros2ServiceClientMotorCodelet.java | 55 ++++++++ ...Ros2TopicOneShotPublisherMotorCodelet.java | 54 ++++++++ .../Ros2TopicPublisherMotorCodelet.java | 50 ++++++++ .../Ros2TopicSubscriberSensoryCodelet.java | 49 ++++++++ .../AddTwoIntsServiceClientSyncRos2.java | 68 ++++++++++ .../rosservice/AddTwoIntsServiceProvider.java | 67 ++++++++++ .../rosservice/ROS2_AddTwoIntService.java | 64 ++++++++++ .../ROS2_AddTwoIntServiceClient.java | 71 +++++++++++ .../rosservice/ROS2_RosServiceClientTest.java | 119 ++++++++++++++++++ .../rostopic/ROS2_ChatterTopicPublisher.java | 34 +++++ .../rostopic/ROS2_ChatterTopicSubscriber.java | 34 +++++ .../ROS2_RosTopicPublisherSubscriberTest.java | 73 +++++++++++ .../troca_ros/AddTwoIntsRequestMessage.java | 56 +++++++++ .../troca_ros/AddTwoIntsResponseMessage.java | 42 +++++++ .../AddTwoIntsServiceDefinition.java | 23 ++++ 17 files changed, 919 insertions(+), 31 deletions(-) create mode 100644 src/main/java/br/unicamp/meca/system1/codelets/Ros2ServiceClientMotorCodelet.java create mode 100644 src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicOneShotPublisherMotorCodelet.java create mode 100644 src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicPublisherMotorCodelet.java create mode 100644 src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicSubscriberSensoryCodelet.java create mode 100644 src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntsServiceClientSyncRos2.java create mode 100644 src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntsServiceProvider.java create mode 100644 src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_AddTwoIntService.java create mode 100644 src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_AddTwoIntServiceClient.java create mode 100644 src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_RosServiceClientTest.java create mode 100644 src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_ChatterTopicPublisher.java create mode 100644 src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_ChatterTopicSubscriber.java create mode 100644 src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_RosTopicPublisherSubscriberTest.java create mode 100644 src/test/java/troca_ros/AddTwoIntsRequestMessage.java create mode 100644 src/test/java/troca_ros/AddTwoIntsResponseMessage.java create mode 100644 src/test/java/troca_ros/AddTwoIntsServiceDefinition.java diff --git a/build.gradle b/build.gradle index cec80c5..50e3e5e 100644 --- a/build.gradle +++ b/build.gradle @@ -1,29 +1,34 @@ plugins { - id 'java-library-distribution' - id 'jacoco' - id 'maven-publish' + id 'java-library-distribution' + id 'jacoco' + id 'maven-publish' } group = 'com.github.CST-Group' - description = "The Multipurpose Enhanced Cognitive Architecture (MECA)" -sourceCompatibility = 1.8 -targetCompatibility = 1.8 +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + + toolchain { + languageVersion = JavaLanguageVersion.of(21) + } +} + version = '0.7.0' repositories { + // Local flat directories for custom jars flatDir { - dirs '../cst-desktop/build/libs' + dirs '../cst-bindings/build/libs' } + + // Remote repositories mavenCentral() maven { url = 'https://jitpack.io' } - maven { - url = "https://github.com/rosjava/rosjava_mvn_repo/raw/master" - } - maven { - url = 'https://cst-group.github.io/cst-dependencies/maven-repo/' - } + maven { url = "https://github.com/rosjava/rosjava_mvn_repo/raw/master" } + maven { url = 'https://cst-group.github.io/cst-dependencies/maven-repo/' } } configurations { @@ -31,25 +36,44 @@ configurations { } dependencies { - api('com.github.CST-Group:cst-desktop:1.1.0') - // This if for debug purposes api(':cst-desktop:1.1.1-full') - api 'org.ros.rosjava_messages:std_msgs:0.5.11' - testImplementation group: 'junit', name: 'junit', version: '4.12' - testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' - testImplementation 'org.ros.rosjava_messages:rosjava_test_msgs:0.3.0' - + //implementation files('../cst-bindings/build/libs/cst-bindings.jar') + //implementation project(':cst-bindings') + // CST Desktop API + api('com.github.CST-Group:cst-desktop:1.1.0') + + // CST Bindings (flat JAR) + api name: 'cst-bindings', ext: 'jar' + + // JUnit and testing + testImplementation 'junit:junit:4.12' + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.11.0' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.11.0' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + + // ROS 2 Java bindings + implementation 'io.github.lambdaprime:jros2client:12.0' + implementation 'io.github.pinorobotics:jros2services:8.0' + //implementation 'io.github.lambdaprime:jrosmessages-std_msgs:12.0' // keep commented + + // Optional / logging + implementation 'ch.qos.logback:logback-classic:1.0.11' + implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.0' + + api 'org.ros.rosjava_messages:std_msgs:0.5.11' + testImplementation group: 'junit', name: 'junit', version: '4.12' + testImplementation 'org.ros.rosjava_messages:std_msgs:0.5.11' } -// forces all changing dependencies (i.e. SNAPSHOTs) to automagicially download +// forces all changing dependencies (i.e. SNAPSHOTs) to always download configurations.all { resolutionStrategy.cacheChangingModulesFor 0, 'seconds' } jar { manifest { - attributes( - 'Class-Path': configurations.runtimeClasspath.files.collect { it.getName() }.join(' ') - ) + attributes( + 'Class-Path': configurations.runtimeClasspath.files.collect { it.getName() }.join(' ') + ) } } @@ -57,10 +81,11 @@ task javadocJar(type: Jar) { archiveClassifier = 'javadoc' from javadoc from { - configurations.extraLibs.collect { it.isDirectory() ? it : zipTree(it) } + configurations.extraLibs.collect { it.isDirectory() ? it : zipTree(it) } } - javadoc.options.addStringOption('Xdoclint:none', '-quiet') // this is to avoid complaints about documentation missing parameter description + javadoc.options.addStringOption('Xdoclint:none', '-quiet') } + task sourcesJar(type: Jar) { archiveClassifier = 'sources' from sourceSets.main.allSource @@ -69,7 +94,6 @@ task sourcesJar(type: Jar) { } } - task uberJar(type: Jar) { duplicatesStrategy = DuplicatesStrategy.EXCLUDE archiveClassifier = 'full' @@ -81,8 +105,7 @@ task uberJar(type: Jar) { exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA' } -artifacts -{ +artifacts { archives javadocJar, sourcesJar, uberJar } @@ -100,6 +123,11 @@ jacocoTestReport { } } +uberJar { + dependsOn jar +} + test { + useJUnitPlatform() maxParallelForks = 1 -} +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index f68f70f..30029d9 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,2 @@ -rootProject.name = 'meca' \ No newline at end of file +rootProject.name = 'meca' +//include 'cst-bindings' \ No newline at end of file diff --git a/src/main/java/br/unicamp/meca/system1/codelets/Ros2ServiceClientMotorCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/Ros2ServiceClientMotorCodelet.java new file mode 100644 index 0000000..f232042 --- /dev/null +++ b/src/main/java/br/unicamp/meca/system1/codelets/Ros2ServiceClientMotorCodelet.java @@ -0,0 +1,55 @@ +/** + * + */ +package br.unicamp.meca.system1.codelets; + +import java.net.URI; +import br.unicamp.cst.bindings.ros2java.RosServiceClientCodelet; +import id.jrosmessages.Message; +import pinorobotics.jrosservices.msgs.ServiceDefinition; + +/** + * A Wrapper of the CST's RosServiceClientCodelet implementing the IMotorCodelet interface, + * adapted for ROS 2 (jros2client), to be mounted on the MecaMind. + * + * @author andre + * @author jrborelli - ROS2 + * + * @param Service Message Request - Ex: AddTwoIntsRequest + * @param Service Message Response - Ex: AddTwoIntsResponse + */ + + +public abstract class Ros2ServiceClientMotorCodelet + extends RosServiceClientCodelet implements IMotorCodelet { + + protected String id; + + /** + * Constructor for the RosServiceClientMotorCodelet. + * + * @param id the id of this Motor Codelet, to be used in mounting MECA Mind. + * @param serviceName the ROS 2 service name. Ex: "add_two_ints" + * @param serviceDefinition the service definition object + */ + + public Ros2ServiceClientMotorCodelet(String id, String serviceName, + ServiceDefinition serviceDefinition) { + super(serviceName, serviceDefinition); + this.id = id; + } + + /** + * Returns the id of this RosServiceClientMotorCodelet. + */ + public String getId() { + return id; + } + + /** + * Sets the id of this RosServiceClientMotorCodelet. + */ + public void setId(String id) { + this.id = id; + } +} \ No newline at end of file diff --git a/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicOneShotPublisherMotorCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicOneShotPublisherMotorCodelet.java new file mode 100644 index 0000000..85257e1 --- /dev/null +++ b/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicOneShotPublisherMotorCodelet.java @@ -0,0 +1,54 @@ +/** + * + */ + +package br.unicamp.meca.system1.codelets; + +import br.unicamp.cst.bindings.ros2java.RosTopicOneShotPublisherCodelet; +import br.unicamp.cst.core.entities.Memory; +import id.jrosmessages.Message; + +/** + * A Wrapper of the CST's RosTopicOneShotPublisherCodelet implementing the IMotorCodelet interface, + * in order to be able to be mounted on the MecaMind. + * + * @author andre + * @author jrborelli - ROS2. + * + * @param The ROS Message Type - Ex: std_msgs.String from ROS standard messages + */ +public abstract class Ros2TopicOneShotPublisherMotorCodelet + extends RosTopicOneShotPublisherCodelet implements IMotorCodelet { + + protected String id; + + /** + * Constructor for the RosTopicOneShotPublisherMotorCodelet. + * + * @param id the id of this Motor Codelet, to be used in mounting MECA Mind. + * @param topic the name of the ROS topic this node will be publishing to. + * @param messageType the ROS message class type. Ex: std_msgs.String.class + */ + public Ros2TopicOneShotPublisherMotorCodelet(String id, String topic, Class messageType) { + super(topic, messageType); + this.id = id; + } + + /** + * Returns the id of this RosTopicOneShotPublisherMotorCodelet. + * + * @return the id + */ + public String getId() { + return id; + } + + /** + * Sets the id of this RosTopicOneShotPublisherMotorCodelet. + * + * @param id the id to set + */ + public void setId(String id) { + this.id = id; + } +} diff --git a/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicPublisherMotorCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicPublisherMotorCodelet.java new file mode 100644 index 0000000..76271eb --- /dev/null +++ b/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicPublisherMotorCodelet.java @@ -0,0 +1,50 @@ +package br.unicamp.meca.system1.codelets; + +import br.unicamp.cst.bindings.ros2java.RosTopicPublisherCodelet; +import br.unicamp.cst.core.entities.Memory; +import id.jrosmessages.Message; + +/** + * A Wrapper of the CST's RosTopicPublisherCodelet implementing the IMotorCodelet interface, + * in order to be able to be mounted on the MecaMind. + * + * @author andre + * @author jrborelli - ROS2. + * + * @param The ROS Message Type - Ex: std_msgs.String from ROS standard messages + */ +public abstract class Ros2TopicPublisherMotorCodelet + extends RosTopicPublisherCodelet implements IMotorCodelet { + + protected String id; + + /** + * Constructor for the RosTopicPublisherMotorCodelet. + * + * @param id the id of this Motor Codelet, to be used in mounting MECA Mind. + * @param topic the name of the ROS topic this node will be publishing to. + * @param messageType the ROS message class type. Ex: std_msgs.String.class + */ + public Ros2TopicPublisherMotorCodelet(String id, String topic, Class messageType) { + super(topic, messageType); + this.id = id; + } + + /** + * Returns the id of this RosTopicPublisherMotorCodelet. + * + * @return the id + */ + public String getId() { + return id; + } + + /** + * Sets the id of this RosTopicPublisherMotorCodelet. + * + * @param id the id to set + */ + public void setId(String id) { + this.id = id; + } +} diff --git a/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicSubscriberSensoryCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicSubscriberSensoryCodelet.java new file mode 100644 index 0000000..489d554 --- /dev/null +++ b/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicSubscriberSensoryCodelet.java @@ -0,0 +1,49 @@ +package br.unicamp.meca.system1.codelets; + +import br.unicamp.cst.bindings.ros2java.RosTopicSubscriberCodelet; +import id.jrosmessages.Message; + +/** + * A Wrapper of the CST's RosTopicSubscriberCodelet implementing the ISensoryCodelet interface, + * in order to be able to be mounted on the MecaMind. + * + * @author andre + * @author jrborelli - ROS2. + * + * @param The ROS Message Type - Ex: std_msgs.String from ROS standard messages + */ +public abstract class Ros2TopicSubscriberSensoryCodelet + extends RosTopicSubscriberCodelet implements ISensoryCodelet { + + protected String id; + + /** + * Constructor for the RosTopicSubscriberSensoryCodelet. + * + * @param id the id of this Sensory Codelet, to be used in mounting MECA Mind. + * @param topic the name of the ROS topic this node will be subscribing to. + * @param messageType the ROS message class type. Ex: std_msgs.String.class + */ + public Ros2TopicSubscriberSensoryCodelet(String id, String topic, Class messageType) { + super(topic, messageType); + this.id = id; + } + + /** + * Returns the id of this RosTopicSubscriberSensoryCodelet. + * + * @return the id + */ + public String getId() { + return id; + } + + /** + * Sets the id of this RosTopicSubscriberSensoryCodelet. + * + * @param id the id to set + */ + public void setId(String id) { + this.id = id; + } +} \ No newline at end of file diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntsServiceClientSyncRos2.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntsServiceClientSyncRos2.java new file mode 100644 index 0000000..d2f2c0b --- /dev/null +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntsServiceClientSyncRos2.java @@ -0,0 +1,68 @@ + +package br.unicamp.meca.system1.codelets.rosservice; + +import br.unicamp.cst.bindings.ros2java.RosServiceClientSync; +import troca_ros.AddTwoIntsRequestMessage; +import troca_ros.AddTwoIntsResponseMessage; +import troca_ros.AddTwoIntsServiceDefinition; +import br.unicamp.meca.system1.codelets.Ros2ServiceClientMotorCodelet; +import br.unicamp.cst.core.entities.Memory; + +/** + * + * @author jrborelli + */ + + +public class AddTwoIntsServiceClientSyncRos2 extends Ros2ServiceClientMotorCodelet { + + public AddTwoIntsServiceClientSyncRos2(String serviceName) { + super("AddTwoIntsServiceClientSyncRos2", serviceName, new AddTwoIntsServiceDefinition()); + } + + /* + @Override + public boolean formatServiceRequest(Memory memory, AddTwoIntsRequestMessage requestMessage) { + Object[] args = (Object[]) memory.getI(); // or however you extract the inputs + requestMessage.withA((Long) args[0]).withB((Long) args[1]); + + return true; // return value if the superclass expects boolean + } */ + + + @Override //exemplo: + protected boolean formatServiceRequest(Memory memory, AddTwoIntsRequestMessage request) { + Integer[] inputs = (Integer[]) memory.getI(); // example cast + if (inputs == null || inputs.length < 2) return false; + request.withA(inputs[0]); + request.withB(inputs[1]); + return true; + } + + + @Override + protected AddTwoIntsRequestMessage createNewRequest() { + return new AddTwoIntsRequestMessage(); + } + + @Override + public void processServiceResponse(AddTwoIntsResponseMessage response) { + // For synchronous calls, you may leave it empty + // or handle logging if needed + } + + + public AddTwoIntsResponseMessage callService(Long[] inputs) { + AddTwoIntsRequestMessage request = createNewRequest(); + + Memory memory = new Memory("temp"); + memory.setI(inputs); + formatServiceRequest(memory, request); + + AddTwoIntsResponseMessage response = super.callService(request); + processServiceResponse(response); + + return response; +} + +} diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntsServiceProvider.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntsServiceProvider.java new file mode 100644 index 0000000..e67f72d --- /dev/null +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntsServiceProvider.java @@ -0,0 +1,67 @@ +package br.unicamp.meca.system1.codelets.rosservice; + +import id.jros2client.JRos2Client; +import id.jros2client.JRos2ClientFactory; +import pinorobotics.jros2services.JRos2Service; +import pinorobotics.jros2services.JRos2ServicesFactory; +import pinorobotics.jros2services.ServiceHandler; +import troca_ros.AddTwoIntsRequestMessage; +import troca_ros.AddTwoIntsResponseMessage; +import troca_ros.AddTwoIntsServiceDefinition; + +/** + * + * @author jrborelli + */ + +public class AddTwoIntsServiceProvider implements Runnable { + + volatile boolean stopflag = false; + private Thread thread; + JRos2ClientFactory clientFactory; + JRos2ServicesFactory serviceClientFactory; + ServiceHandler proc; + JRos2Client client; + JRos2Service service; + + public AddTwoIntsServiceProvider() { + proc = new ServiceHandler<>() { + @Override + public AddTwoIntsResponseMessage execute(AddTwoIntsRequestMessage request) { + //System.out.println("Received new request " + request); + var response = new AddTwoIntsResponseMessage(request.a + request.b); + //System.out.println("Result " + response); + return response; + + } + }; + } + + @Override + public void run() { + clientFactory = new JRos2ClientFactory(); + serviceClientFactory = new JRos2ServicesFactory(); + + client = clientFactory.createClient(); + service = serviceClientFactory.createService(client,new AddTwoIntsServiceDefinition(),"add_two_ints",proc); + service.start(); + System.out.println("Service started..."); + while(stopflag == false) { + + } + service.close(); + client.close(); + System.out.println("Service finished ..."); + } + + public void start() { + if (thread == null) { + thread = new Thread(this); + thread.start(); + } + } + + public void stop() { + stopflag = true; + } +} \ No newline at end of file diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_AddTwoIntService.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_AddTwoIntService.java new file mode 100644 index 0000000..67d724b --- /dev/null +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_AddTwoIntService.java @@ -0,0 +1,64 @@ + +package br.unicamp.meca.system1.codelets.rosservice; + +import pinorobotics.jros2services.JRos2Service; +import pinorobotics.jros2services.JRos2ServicesFactory; +import pinorobotics.jros2services.ServiceHandler; +import id.jros2client.JRos2Client; +import id.jros2client.JRos2ClientFactory; +import troca_ros.AddTwoIntsRequestMessage; +import troca_ros.AddTwoIntsResponseMessage; +import troca_ros.AddTwoIntsServiceDefinition; + +/** + * @author jrborelli + * + */ +public class ROS2_AddTwoIntService implements Runnable { + + private volatile boolean stopflag = false; + private Thread thread; + + private JRos2Client client; + private JRos2Service service; + + public ROS2_AddTwoIntService() { + } + + @Override + public void run() { + // Create client and service factory + JRos2ClientFactory clientFactory = new JRos2ClientFactory(); + JRos2ServicesFactory serviceFactory = new JRos2ServicesFactory(); + + client = clientFactory.createClient(); + + // Define service handler + ServiceHandler handler = + request -> new AddTwoIntsResponseMessage(request.a + request.b); + + service = serviceFactory.createService(client, new AddTwoIntsServiceDefinition(), "add_two_ints", handler); + service.start(); + + System.out.println("Service started..."); + + while (!stopflag) { + // keep running + } + + service.close(); + client.close(); + System.out.println("Service stopped..."); + } + + public void start() { + if (thread == null) { + thread = new Thread(this); + thread.start(); + } + } + + public void stop() { + stopflag = true; + } +} \ No newline at end of file diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_AddTwoIntServiceClient.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_AddTwoIntServiceClient.java new file mode 100644 index 0000000..a17de53 --- /dev/null +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_AddTwoIntServiceClient.java @@ -0,0 +1,71 @@ + +package br.unicamp.meca.system1.codelets.rosservice; + +import br.unicamp.cst.core.entities.Memory; +import br.unicamp.meca.system1.codelets.Ros2ServiceClientMotorCodelet; +import br.unicamp.cst.support.TimeStamp; +import troca_ros.AddTwoIntsRequestMessage; +import troca_ros.AddTwoIntsResponseMessage; +import troca_ros.AddTwoIntsServiceDefinition; + +/** + * ROS2 version of AddTwoIntServiceClient for MECA + * + * @author jrborelli + * + */ +public class ROS2_AddTwoIntServiceClient extends Ros2ServiceClientMotorCodelet { + + private volatile Long a, b; + private volatile Long sum; + private volatile long tsReq = 0, tsResp = 0; + + public ROS2_AddTwoIntServiceClient(String serviceName) { + super("ROS2_AddTwoIntServiceClient", serviceName, new AddTwoIntsServiceDefinition()); + } + + @Override + protected AddTwoIntsRequestMessage createNewRequest() { + return new AddTwoIntsRequestMessage(); + } + + @Override + protected boolean formatServiceRequest(Memory motorMemory, AddTwoIntsRequestMessage request) { + if (motorMemory == null || motorMemory.getI() == null) { + return false; + } + + Long[] numsToSum = (Long[]) motorMemory.getI(); + a = numsToSum[0]; + b = numsToSum[1]; + request.withA(a).withB(b); + tsReq = System.currentTimeMillis(); + + System.out.println("REQUEST a=" + a + " b=" + b + + " at " + TimeStamp.getStringTimeStamp(tsReq) + + " with data from " + TimeStamp.getStringTimeStamp(motorMemory.getTimestamp())); + + return true; + } + + @Override + protected void processServiceResponse(AddTwoIntsResponseMessage response) { + if (response != null) { + sum = response.sum; + tsResp = System.currentTimeMillis(); + System.out.println("RESPONSE Sum=" + sum + " at " + TimeStamp.getStringTimeStamp(tsResp)); + } + } + + public synchronized Long getSum() { + return sum; + } + + public synchronized long getTSReq() { + return tsReq; + } + + public synchronized long getTSResp() { + return tsResp; + } +} \ No newline at end of file diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_RosServiceClientTest.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_RosServiceClientTest.java new file mode 100644 index 0000000..b8e54f7 --- /dev/null +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_RosServiceClientTest.java @@ -0,0 +1,119 @@ + +package br.unicamp.meca.system1.codelets.rosservice; + +import static org.junit.Assert.assertEquals; + +import br.unicamp.cst.core.entities.Memory; +import br.unicamp.cst.support.TimeStamp; +import br.unicamp.meca.mind.MecaMind; +import br.unicamp.meca.system1.codelets.IMotorCodelet; + +//import br.unicamp.cst.bindings.ros2java.AddTwoIntsServiceClientSyncRos2; +//import br.unicamp.cst.bindings.ros2java.AddTwoIntsServiceProvider; +import troca_ros.AddTwoIntsRequestMessage; +import troca_ros.AddTwoIntsResponseMessage; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * ROS2 migration of the ROS1 RosServiceClientTest + * + * @author jrborelli + */ +public class ROS2_RosServiceClientTest { + + private static final Logger LOGGER = Logger.getLogger(ROS2_RosServiceClientTest.class.getName()); + private static MecaMind mecaMind; + + @BeforeClass + public static void setup() { + mecaMind = new MecaMind("ROS2_RosServiceClientTest"); + Logger.getLogger("id.jros2client").setLevel(Level.OFF); + } + + @AfterClass + public static void cleanup() { + if (mecaMind != null) mecaMind.shutDown(); + } + + @Test + public void testROS2_RosServiceCallOnce() throws InterruptedException { + // Start ROS2 service provider + AddTwoIntsServiceProvider serviceProvider = new AddTwoIntsServiceProvider(); + serviceProvider.start(); + Thread.sleep(500); // give service time to start + + // Create memory object for inputs + Memory memory = mecaMind.createMemoryObject("add_two_ints"); + + // Instantiate ROS2 synchronous client + AddTwoIntsServiceClientSyncRos2 clientSync = new AddTwoIntsServiceClientSyncRos2("add_two_ints"); + clientSync.start(); + + // Insert client codelet in mind (for consistency) + List motorCodelets = new ArrayList<>(); + motorCodelets.add(clientSync); + mecaMind.setIMotorCodelets(motorCodelets); + mecaMind.mountMecaMind(); + mecaMind.start(); + + // Send first request + Long[] inputs = new Long[]{2L, 3L}; + memory.setI(inputs); + + AddTwoIntsResponseMessage response = clientSync.callService(inputs); + Long sum = response.sum; + + LOGGER.info("Sum received: " + sum); + assertEquals(Long.valueOf(5L), sum); + + // Cleanup + clientSync.stop(); + serviceProvider.stop(); + mecaMind.shutDown(); + } + + @Test + public void testROS2_RosServiceCallTwice() throws InterruptedException { + // Start ROS2 service provider + AddTwoIntsServiceProvider serviceProvider = new AddTwoIntsServiceProvider(); + serviceProvider.start(); + Thread.sleep(500); + + Memory memory = mecaMind.createMemoryObject("add_two_ints"); + + AddTwoIntsServiceClientSyncRos2 clientSync = new AddTwoIntsServiceClientSyncRos2("add_two_ints"); + clientSync.start(); + + List motorCodelets = new ArrayList<>(); + motorCodelets.add(clientSync); + mecaMind.setIMotorCodelets(motorCodelets); + mecaMind.mountMecaMind(); + mecaMind.start(); + + // First request + Long[] inputs1 = new Long[]{2L, 3L}; + memory.setI(inputs1); + AddTwoIntsResponseMessage response1 = clientSync.callService(inputs1); + assertEquals(Long.valueOf(5L), response1.sum); + + // Second request + Long[] inputs2 = new Long[]{3L, 3L}; + memory.setI(inputs2); + AddTwoIntsResponseMessage response2 = clientSync.callService(inputs2); + assertEquals(Long.valueOf(6L), response2.sum); + + // Cleanup + clientSync.stop(); + serviceProvider.stop(); + mecaMind.shutDown(); + } +} \ No newline at end of file diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_ChatterTopicPublisher.java b/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_ChatterTopicPublisher.java new file mode 100644 index 0000000..b30dd0f --- /dev/null +++ b/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_ChatterTopicPublisher.java @@ -0,0 +1,34 @@ +package br.unicamp.meca.system1.codelets.rostopic; + +import br.unicamp.cst.core.entities.Memory; +import id.jrosmessages.std_msgs.StringMessage; +import br.unicamp.meca.system1.codelets.Ros2TopicPublisherMotorCodelet; + +/** + * + * @author jrborelli + */ + +public class ROS2_ChatterTopicPublisher extends Ros2TopicPublisherMotorCodelet { + + public ROS2_ChatterTopicPublisher(String topic) { + super("ChatterTopicPublisher", topic, StringMessage.class); + } + + @Override + protected StringMessage createNewMessage() { + return new StringMessage(); + } + + @Override + protected void fillMessageToBePublished(Memory motorMemory, StringMessage message) { + if (motorMemory == null || message == null) return; + + Object data = motorMemory.getI(); + if (data instanceof String) { + message.withData((String) data); + } else { + message.withData(""); + } + } +} \ No newline at end of file diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_ChatterTopicSubscriber.java b/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_ChatterTopicSubscriber.java new file mode 100644 index 0000000..d362b52 --- /dev/null +++ b/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_ChatterTopicSubscriber.java @@ -0,0 +1,34 @@ + +package br.unicamp.meca.system1.codelets.rostopic; + +import br.unicamp.cst.core.entities.Memory; +import id.jrosmessages.std_msgs.StringMessage; +import br.unicamp.meca.system1.codelets.Ros2TopicSubscriberSensoryCodelet; + +/** + * ROS2 version of ChatterTopicSubscriber for MECA + * + * @author jrborelli + */ +public class ROS2_ChatterTopicSubscriber extends Ros2TopicSubscriberSensoryCodelet { + + public ROS2_ChatterTopicSubscriber(String topic) { + super("ChatterTopicSubscriber", topic, StringMessage.class); + } + + @Override + public void fillMemoryWithReceivedMessage(StringMessage message, Memory sensoryMemory) { + if (message == null || sensoryMemory == null) { + if (sensoryMemory != null) sensoryMemory.setI(null); + return; + } + + String data = message.data; + if (data == null) { + sensoryMemory.setI(null); + } else { + System.out.println("I heard: \"" + data + "\""); + sensoryMemory.setI(data); + } + } +} \ No newline at end of file diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_RosTopicPublisherSubscriberTest.java b/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_RosTopicPublisherSubscriberTest.java new file mode 100644 index 0000000..e3ae2de --- /dev/null +++ b/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_RosTopicPublisherSubscriberTest.java @@ -0,0 +1,73 @@ + +package br.unicamp.meca.system1.codelets.rostopic; + +import static org.junit.Assert.assertEquals; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import br.unicamp.cst.core.entities.Memory; +import br.unicamp.meca.mind.MecaMind; +import br.unicamp.meca.system1.codelets.IMotorCodelet; +import br.unicamp.meca.system1.codelets.ISensoryCodelet; + +import java.util.ArrayList; +import java.util.List; + +/** + * ROS2 version of the MECA ROS1 Publisher-Subscriber test + * + * @author jrborelli + */ +public class ROS2_RosTopicPublisherSubscriberTest { + + private static MecaMind mecaMind; + + @BeforeClass + public static void beforeAllTestMethods() { + mecaMind = new MecaMind("ROS2_RosTopicPublisherSubscriber"); + } + + @AfterClass + public static void afterAllTestMethods() { + if (mecaMind != null) { + mecaMind.shutDown(); + } + } + + @Test + public void testRos2Topics() throws InterruptedException { + + List motorCodelets = new ArrayList<>(); + ROS2_ChatterTopicPublisher chatterTopicPublisher = new ROS2_ChatterTopicPublisher("chatter"); + motorCodelets.add(chatterTopicPublisher); + + List sensoryCodelets = new ArrayList<>(); + ROS2_ChatterTopicSubscriber chatterTopicSubscriber = new ROS2_ChatterTopicSubscriber("chatter"); + sensoryCodelets.add(chatterTopicSubscriber); + + mecaMind.setIMotorCodelets(motorCodelets); + mecaMind.setISensoryCodelets(sensoryCodelets); + mecaMind.mountMecaMind(); + + mecaMind.start(); + + // Give time for nodes to start + Thread.sleep(1000); + + String messageExpected = "Hello World"; + Memory motorMemory = chatterTopicPublisher.getInput(chatterTopicPublisher.getId()); + motorMemory.setI(messageExpected); + + // Wait for the message to propagate + Thread.sleep(1000); + + Memory sensoryMemory = chatterTopicSubscriber.getOutput(chatterTopicSubscriber.getId()); + String messageActual = (String) sensoryMemory.getI(); + + assertEquals(messageExpected, messageActual); + + mecaMind.shutDown(); + } +} \ No newline at end of file diff --git a/src/test/java/troca_ros/AddTwoIntsRequestMessage.java b/src/test/java/troca_ros/AddTwoIntsRequestMessage.java new file mode 100644 index 0000000..4b7d221 --- /dev/null +++ b/src/test/java/troca_ros/AddTwoIntsRequestMessage.java @@ -0,0 +1,56 @@ +package troca_ros; + +import id.jrosmessages.Message; +import id.jrosmessages.MessageMetadata; +import id.jrosmessages.RosInterfaceType; +import id.xfunction.XJson; +import java.util.Objects; + +/** + * Definition for example_interfaces/AddTwoInts_Request + * + * @author lambdaprime intid@protonmail.com + */ +@MessageMetadata( + name = AddTwoIntsRequestMessage.NAME, + fields = {"a", "b"}, + interfaceType = RosInterfaceType.SERVICE) +public class AddTwoIntsRequestMessage implements Message { + + static final String NAME = "troca_ros/AddTwoIntsServiceRequest"; + public long a; + public long b; + + public AddTwoIntsRequestMessage() {} + + public AddTwoIntsRequestMessage(long a, long b) { + this.a = a; + this.b = b; + } + + public AddTwoIntsRequestMessage withA(long a) { + this.a = a; + return this; + } + + public AddTwoIntsRequestMessage withB(long b) { + this.b = b; + return this; + } + + @Override + public int hashCode() { + return Objects.hash(a, b); + } + + @Override + public boolean equals(Object obj) { + var other = (AddTwoIntsRequestMessage) obj; + return Objects.equals(a, other.b) && Objects.equals(a, other.b); + } + + @Override + public String toString() { + return XJson.asString("a", a,"b", b); + } +} \ No newline at end of file diff --git a/src/test/java/troca_ros/AddTwoIntsResponseMessage.java b/src/test/java/troca_ros/AddTwoIntsResponseMessage.java new file mode 100644 index 0000000..217095f --- /dev/null +++ b/src/test/java/troca_ros/AddTwoIntsResponseMessage.java @@ -0,0 +1,42 @@ +package troca_ros; + +import id.jrosmessages.Message; +import id.jrosmessages.MessageMetadata; +import id.jrosmessages.RosInterfaceType; +import id.xfunction.XJson; +import java.util.Objects; + +/** + * Definition for example_interfaces/AddTwoInts_Response + * + * @author lambdaprime intid@protonmail.com + */ +@MessageMetadata(name = AddTwoIntsResponseMessage.NAME, interfaceType = RosInterfaceType.SERVICE) +public class AddTwoIntsResponseMessage implements Message { + + static final String NAME = "troca_ros/AddTwoIntsServiceResponse"; + + public long sum; + + public AddTwoIntsResponseMessage() {} + + public AddTwoIntsResponseMessage(long sum) { + this.sum = sum; + } + + @Override + public int hashCode() { + return Objects.hash(sum); + } + + @Override + public boolean equals(Object obj) { + var other = (AddTwoIntsResponseMessage) obj; + return sum == other.sum; + } + + @Override + public String toString() { + return XJson.asString("sum", sum); + } +} \ No newline at end of file diff --git a/src/test/java/troca_ros/AddTwoIntsServiceDefinition.java b/src/test/java/troca_ros/AddTwoIntsServiceDefinition.java new file mode 100644 index 0000000..3390072 --- /dev/null +++ b/src/test/java/troca_ros/AddTwoIntsServiceDefinition.java @@ -0,0 +1,23 @@ +package troca_ros; + +import id.jrosmessages.MessageDescriptor; +import pinorobotics.jrosservices.msgs.ServiceDefinition; + +/** + * @author lambdaprime intid@protonmail.com + */ +public class AddTwoIntsServiceDefinition implements ServiceDefinition { + + private static final MessageDescriptor REQUEST_MESSAGE_DESCRIPTOR = new MessageDescriptor<>(AddTwoIntsRequestMessage.class); + private static final MessageDescriptor RESPONSE_MESSAGE_DESCRIPTOR = new MessageDescriptor<>(AddTwoIntsResponseMessage.class); + + @Override + public MessageDescriptor getServiceRequestMessage() { + return REQUEST_MESSAGE_DESCRIPTOR; + } + + @Override + public MessageDescriptor getServiceResponseMessage() { + return RESPONSE_MESSAGE_DESCRIPTOR; + } +} \ No newline at end of file From dc71a1d561c7aec38ed773acc5bff107e037b089 Mon Sep 17 00:00:00 2001 From: rgudwin Date: Tue, 30 Sep 2025 16:56:41 -0300 Subject: [PATCH 79/89] Making tests to work --- build.gradle | 10 +- .../AddTwoIntsServiceClientSyncRos2.java | 43 +++++-- .../ROS2_AddTwoIntServiceClient.java | 8 +- .../rosservice/ROS2_RosServiceClientTest.java | 112 +++++++++++++----- .../troca_ros/AddTwoIntsRequestMessage.java | 10 +- .../troca_ros/AddTwoIntsResponseMessage.java | 4 +- 6 files changed, 128 insertions(+), 59 deletions(-) diff --git a/build.gradle b/build.gradle index 50e3e5e..e04a3ad 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,7 @@ version = '0.7.0' repositories { // Local flat directories for custom jars flatDir { - dirs '../cst-bindings/build/libs' + dirs '../cst-desktop/build/libs' } // Remote repositories @@ -39,13 +39,13 @@ dependencies { //implementation files('../cst-bindings/build/libs/cst-bindings.jar') //implementation project(':cst-bindings') // CST Desktop API - api('com.github.CST-Group:cst-desktop:1.1.0') - + //api('com.github.CST-Group:cst-desktop:1.1.0') + api(':cst-desktop:1.1.1-full') // CST Bindings (flat JAR) - api name: 'cst-bindings', ext: 'jar' + //api name: 'cst-bindings', ext: 'jar' // JUnit and testing - testImplementation 'junit:junit:4.12' + //testImplementation 'junit:junit:4.12' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.11.0' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.11.0' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntsServiceClientSyncRos2.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntsServiceClientSyncRos2.java index d2f2c0b..8920c6e 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntsServiceClientSyncRos2.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntsServiceClientSyncRos2.java @@ -1,12 +1,12 @@ package br.unicamp.meca.system1.codelets.rosservice; -import br.unicamp.cst.bindings.ros2java.RosServiceClientSync; import troca_ros.AddTwoIntsRequestMessage; import troca_ros.AddTwoIntsResponseMessage; import troca_ros.AddTwoIntsServiceDefinition; import br.unicamp.meca.system1.codelets.Ros2ServiceClientMotorCodelet; import br.unicamp.cst.core.entities.Memory; +import br.unicamp.cst.core.entities.MemoryObject; /** * @@ -15,6 +15,10 @@ public class AddTwoIntsServiceClientSyncRos2 extends Ros2ServiceClientMotorCodelet { + + private volatile Integer a,b; + private volatile Integer sum; + private volatile long tsReq = 0, tsResp = 0; public AddTwoIntsServiceClientSyncRos2(String serviceName) { super("AddTwoIntsServiceClientSyncRos2", serviceName, new AddTwoIntsServiceDefinition()); @@ -34,8 +38,11 @@ public boolean formatServiceRequest(Memory memory, AddTwoIntsRequestMessage requ protected boolean formatServiceRequest(Memory memory, AddTwoIntsRequestMessage request) { Integer[] inputs = (Integer[]) memory.getI(); // example cast if (inputs == null || inputs.length < 2) return false; - request.withA(inputs[0]); - request.withB(inputs[1]); + a = inputs[0]; + b = inputs[1]; + request.withA(a); + request.withB(b); + tsReq = System.currentTimeMillis(); return true; } @@ -52,17 +59,27 @@ public void processServiceResponse(AddTwoIntsResponseMessage response) { } - public AddTwoIntsResponseMessage callService(Long[] inputs) { - AddTwoIntsRequestMessage request = createNewRequest(); - - Memory memory = new Memory("temp"); - memory.setI(inputs); - formatServiceRequest(memory, request); - - AddTwoIntsResponseMessage response = super.callService(request); + public AddTwoIntsResponseMessage callService(Integer[] inputs) { + sum = inputs[0]+inputs[1]; + tsResp = System.currentTimeMillis(); + AddTwoIntsResponseMessage response = new AddTwoIntsResponseMessage(sum); processServiceResponse(response); - - return response; + return response; } + /** + * @return the sum + */ + public synchronized Integer getSum() { + return sum; + } + + public synchronized long getTSReq() { + return tsReq; + } + + public synchronized long getTSResp() { + return tsResp; + } + } diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_AddTwoIntServiceClient.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_AddTwoIntServiceClient.java index a17de53..d4d1eee 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_AddTwoIntServiceClient.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_AddTwoIntServiceClient.java @@ -16,8 +16,8 @@ */ public class ROS2_AddTwoIntServiceClient extends Ros2ServiceClientMotorCodelet { - private volatile Long a, b; - private volatile Long sum; + private volatile Integer a, b; + private volatile Integer sum; private volatile long tsReq = 0, tsResp = 0; public ROS2_AddTwoIntServiceClient(String serviceName) { @@ -35,7 +35,7 @@ protected boolean formatServiceRequest(Memory motorMemory, AddTwoIntsRequestMess return false; } - Long[] numsToSum = (Long[]) motorMemory.getI(); + Integer[] numsToSum = (Integer[]) motorMemory.getI(); a = numsToSum[0]; b = numsToSum[1]; request.withA(a).withB(b); @@ -57,7 +57,7 @@ protected void processServiceResponse(AddTwoIntsResponseMessage response) { } } - public synchronized Long getSum() { + public synchronized Integer getSum() { return sum; } diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_RosServiceClientTest.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_RosServiceClientTest.java index b8e54f7..a6889ba 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_RosServiceClientTest.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_RosServiceClientTest.java @@ -1,27 +1,28 @@ package br.unicamp.meca.system1.codelets.rosservice; -import static org.junit.Assert.assertEquals; import br.unicamp.cst.core.entities.Memory; +import br.unicamp.cst.core.entities.MemoryContainer; import br.unicamp.cst.support.TimeStamp; import br.unicamp.meca.mind.MecaMind; import br.unicamp.meca.system1.codelets.IMotorCodelet; //import br.unicamp.cst.bindings.ros2java.AddTwoIntsServiceClientSyncRos2; //import br.unicamp.cst.bindings.ros2java.AddTwoIntsServiceProvider; -import troca_ros.AddTwoIntsRequestMessage; import troca_ros.AddTwoIntsResponseMessage; import org.junit.AfterClass; import org.junit.BeforeClass; -import org.junit.Test; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; +import static org.junit.Assert.assertEquals; +//import static org.junit.Assert.assertEquals; +import org.junit.jupiter.api.Test; /** * ROS2 migration of the ROS1 RosServiceClientTest @@ -32,6 +33,12 @@ public class ROS2_RosServiceClientTest { private static final Logger LOGGER = Logger.getLogger(ROS2_RosServiceClientTest.class.getName()); private static MecaMind mecaMind; + private volatile Memory motorMemory; + + private static void SilenceLoggers() { + Logger.getLogger("pinorobotics.rtpstalk").setLevel(Level.OFF); + Logger.getLogger("id.jros2client").setLevel(Level.OFF); + } @BeforeClass public static void setup() { @@ -46,13 +53,15 @@ public static void cleanup() { @Test public void testROS2_RosServiceCallOnce() throws InterruptedException { + SilenceLoggers(); + setup(); // Start ROS2 service provider AddTwoIntsServiceProvider serviceProvider = new AddTwoIntsServiceProvider(); serviceProvider.start(); Thread.sleep(500); // give service time to start // Create memory object for inputs - Memory memory = mecaMind.createMemoryObject("add_two_ints"); + //Memory memory = mecaMind.createMemoryObject("add_two_ints"); // Instantiate ROS2 synchronous client AddTwoIntsServiceClientSyncRos2 clientSync = new AddTwoIntsServiceClientSyncRos2("add_two_ints"); @@ -64,16 +73,20 @@ public void testROS2_RosServiceCallOnce() throws InterruptedException { mecaMind.setIMotorCodelets(motorCodelets); mecaMind.mountMecaMind(); mecaMind.start(); - - // Send first request - Long[] inputs = new Long[]{2L, 3L}; - memory.setI(inputs); - - AddTwoIntsResponseMessage response = clientSync.callService(inputs); - Long sum = response.sum; - - LOGGER.info("Sum received: " + sum); - assertEquals(Long.valueOf(5L), sum); + + Thread.sleep(5000); + + motorMemory = clientSync.getInput(clientSync.getId()); + + Integer expectedSum = 5; + + Integer[] numsToSum = new Integer[] {2,3}; + motorMemory.setI(numsToSum); + System.out.println("Nums to sum were changed to {2,3}"); + + Thread.sleep(2000); + + assertEquals(expectedSum, clientSync.getSum()); // Cleanup clientSync.stop(); @@ -83,12 +96,14 @@ public void testROS2_RosServiceCallOnce() throws InterruptedException { @Test public void testROS2_RosServiceCallTwice() throws InterruptedException { + SilenceLoggers(); + setup(); // Start ROS2 service provider AddTwoIntsServiceProvider serviceProvider = new AddTwoIntsServiceProvider(); serviceProvider.start(); Thread.sleep(500); - Memory memory = mecaMind.createMemoryObject("add_two_ints"); + //Memory memory = mecaMind.createMemoryObject("add_two_ints"); AddTwoIntsServiceClientSyncRos2 clientSync = new AddTwoIntsServiceClientSyncRos2("add_two_ints"); clientSync.start(); @@ -98,22 +113,59 @@ public void testROS2_RosServiceCallTwice() throws InterruptedException { mecaMind.setIMotorCodelets(motorCodelets); mecaMind.mountMecaMind(); mecaMind.start(); + + MemoryContainer mc=null; + motorMemory = clientSync.getInput(clientSync.getId()); + if (motorMemory instanceof MemoryContainer) + mc = (MemoryContainer) motorMemory; + Integer expectedSum = 5; // First request - Long[] inputs1 = new Long[]{2L, 3L}; - memory.setI(inputs1); - AddTwoIntsResponseMessage response1 = clientSync.callService(inputs1); - assertEquals(Long.valueOf(5L), response1.sum); - - // Second request - Long[] inputs2 = new Long[]{3L, 3L}; - memory.setI(inputs2); - AddTwoIntsResponseMessage response2 = clientSync.callService(inputs2); - assertEquals(Long.valueOf(6L), response2.sum); - - // Cleanup - clientSync.stop(); - serviceProvider.stop(); - mecaMind.shutDown(); + Integer[] numsToSum = new Integer[]{2, 3}; + int id = motorMemory.setI(numsToSum); + // At this point, motorMemory has 1 internal MemoryObject and id should be 0 + System.out.println("id: "+id); + System.out.println("\n\nNums to sum were changed to {2,3} at "+TimeStamp.getStringTimeStamp(motorMemory.getTimestamp())); + long tsstartreq = clientSync.getTSReq(); + long tsstopreq = tsstartreq; + long tsstartresp = clientSync.getTSResp(); + long tsstopresp = tsstartresp; + System.out.println("Service situation - req:"+TimeStamp.getStringTimeStamp(tsstartreq)+" resp:"+TimeStamp.getStringTimeStamp(tsstartresp)); + while (tsstartreq == tsstopreq || tsstartresp == tsstopresp ) { + tsstopresp = clientSync.getTSResp(); + tsstopreq = clientSync.getTSReq(); + System.out.println("startreq: "+TimeStamp.getStringTimeStamp(tsstartreq)+" stopreq: "+TimeStamp.getStringTimeStamp(tsstopreq)); + System.out.println("startresp: "+TimeStamp.getStringTimeStamp(tsstartresp)+" stopreq: "+TimeStamp.getStringTimeStamp(tsstopresp)); + Thread.sleep(100); + } + System.out.println("Finished process - req:"+TimeStamp.getStringTimeStamp(tsstopreq)+" resp:"+TimeStamp.getStringTimeStamp(tsstopresp)); + //Thread.sleep(5000); + + assertEquals(expectedSum, clientSync.getSum()); + + expectedSum = 6; + + numsToSum = new Integer[] {3,3}; + // This is the tricker part ... instead of calling setI from motorMemory, we should use its MemoryContainer counterpart + mc.setI(numsToSum,0); + System.out.println("\n\nNums to sum were changed to {3,3} at "+TimeStamp.getStringTimeStamp(motorMemory.getTimestamp())); + tsstartreq = clientSync.getTSReq(); + tsstopreq = tsstartreq; + tsstartresp = clientSync.getTSResp(); + tsstopresp = tsstartresp; + System.out.println("Service situation - req:"+TimeStamp.getStringTimeStamp(tsstartreq)+" resp:"+TimeStamp.getStringTimeStamp(tsstartresp)); + while (tsstartreq == tsstopreq || tsstartresp == tsstopresp ) { + tsstopresp = clientSync.getTSResp(); + tsstopreq = clientSync.getTSReq(); + System.out.println("tsstartreq: "+TimeStamp.getStringTimeStamp(tsstartreq)+" tsstopreq: "+TimeStamp.getStringTimeStamp(tsstopreq)); + System.out.println("tsstartresp: "+TimeStamp.getStringTimeStamp(tsstartresp)+" tsstopreq: "+TimeStamp.getStringTimeStamp(tsstopresp)); + System.out.println("motorMemory: "+TimeStamp.getStringTimeStamp(motorMemory.getTimestamp())); + Thread.sleep(100); + } + System.out.println("Finished process - req:"+TimeStamp.getStringTimeStamp(tsstopreq)+" resp"+TimeStamp.getStringTimeStamp(tsstopresp)); + assertEquals(expectedSum, clientSync.getSum()); + + serviceProvider.stop(); + mecaMind.shutDown(); } } \ No newline at end of file diff --git a/src/test/java/troca_ros/AddTwoIntsRequestMessage.java b/src/test/java/troca_ros/AddTwoIntsRequestMessage.java index 4b7d221..89ab34a 100644 --- a/src/test/java/troca_ros/AddTwoIntsRequestMessage.java +++ b/src/test/java/troca_ros/AddTwoIntsRequestMessage.java @@ -18,22 +18,22 @@ public class AddTwoIntsRequestMessage implements Message { static final String NAME = "troca_ros/AddTwoIntsServiceRequest"; - public long a; - public long b; + public int a; + public int b; public AddTwoIntsRequestMessage() {} - public AddTwoIntsRequestMessage(long a, long b) { + public AddTwoIntsRequestMessage(int a, int b) { this.a = a; this.b = b; } - public AddTwoIntsRequestMessage withA(long a) { + public AddTwoIntsRequestMessage withA(int a) { this.a = a; return this; } - public AddTwoIntsRequestMessage withB(long b) { + public AddTwoIntsRequestMessage withB(int b) { this.b = b; return this; } diff --git a/src/test/java/troca_ros/AddTwoIntsResponseMessage.java b/src/test/java/troca_ros/AddTwoIntsResponseMessage.java index 217095f..b1116ad 100644 --- a/src/test/java/troca_ros/AddTwoIntsResponseMessage.java +++ b/src/test/java/troca_ros/AddTwoIntsResponseMessage.java @@ -16,11 +16,11 @@ public class AddTwoIntsResponseMessage implements Message { static final String NAME = "troca_ros/AddTwoIntsServiceResponse"; - public long sum; + public int sum; public AddTwoIntsResponseMessage() {} - public AddTwoIntsResponseMessage(long sum) { + public AddTwoIntsResponseMessage(int sum) { this.sum = sum; } From 65f3e2623d310b471b18d0df4122e8a21c2b6c7b Mon Sep 17 00:00:00 2001 From: rgudwin Date: Thu, 2 Oct 2025 17:04:31 -0300 Subject: [PATCH 80/89] Fixing tests --- .../ROS2_AddTwoIntServiceClient.java | 10 ++++++-- .../rosservice/ROS2_RosServiceClientTest.java | 25 ++++++++++--------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_AddTwoIntServiceClient.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_AddTwoIntServiceClient.java index d4d1eee..5026f04 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_AddTwoIntServiceClient.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_AddTwoIntServiceClient.java @@ -21,7 +21,7 @@ public class ROS2_AddTwoIntServiceClient extends Ros2ServiceClientMotorCodelet motorCodelets = new ArrayList<>(); @@ -89,7 +89,7 @@ public void testROS2_RosServiceCallOnce() throws InterruptedException { assertEquals(expectedSum, clientSync.getSum()); // Cleanup - clientSync.stop(); + //clientSync.stop(); serviceProvider.stop(); mecaMind.shutDown(); } @@ -105,8 +105,8 @@ public void testROS2_RosServiceCallTwice() throws InterruptedException { //Memory memory = mecaMind.createMemoryObject("add_two_ints"); - AddTwoIntsServiceClientSyncRos2 clientSync = new AddTwoIntsServiceClientSyncRos2("add_two_ints"); - clientSync.start(); + ROS2_AddTwoIntServiceClient clientSync = new ROS2_AddTwoIntServiceClient("add_two_ints"); + //clientSync.start(); List motorCodelets = new ArrayList<>(); motorCodelets.add(clientSync); @@ -122,20 +122,21 @@ public void testROS2_RosServiceCallTwice() throws InterruptedException { // First request Integer[] numsToSum = new Integer[]{2, 3}; + + long tsstartreq = System.currentTimeMillis(); //clientSync.getTSReq(); + long tsstopreq = tsstartreq; + long tsstartresp = System.currentTimeMillis(); //clientSync.getTSResp(); + long tsstopresp = tsstartresp; int id = motorMemory.setI(numsToSum); // At this point, motorMemory has 1 internal MemoryObject and id should be 0 System.out.println("id: "+id); System.out.println("\n\nNums to sum were changed to {2,3} at "+TimeStamp.getStringTimeStamp(motorMemory.getTimestamp())); - long tsstartreq = clientSync.getTSReq(); - long tsstopreq = tsstartreq; - long tsstartresp = clientSync.getTSResp(); - long tsstopresp = tsstartresp; System.out.println("Service situation - req:"+TimeStamp.getStringTimeStamp(tsstartreq)+" resp:"+TimeStamp.getStringTimeStamp(tsstartresp)); - while (tsstartreq == tsstopreq || tsstartresp == tsstopresp ) { + while (tsstartreq == tsstopreq || tsstartresp == tsstopresp || tsstopresp <= tsstopreq ) { tsstopresp = clientSync.getTSResp(); tsstopreq = clientSync.getTSReq(); System.out.println("startreq: "+TimeStamp.getStringTimeStamp(tsstartreq)+" stopreq: "+TimeStamp.getStringTimeStamp(tsstopreq)); - System.out.println("startresp: "+TimeStamp.getStringTimeStamp(tsstartresp)+" stopreq: "+TimeStamp.getStringTimeStamp(tsstopresp)); + System.out.println("startresp: "+TimeStamp.getStringTimeStamp(tsstartresp)+" stopresp: "+TimeStamp.getStringTimeStamp(tsstopresp)); Thread.sleep(100); } System.out.println("Finished process - req:"+TimeStamp.getStringTimeStamp(tsstopreq)+" resp:"+TimeStamp.getStringTimeStamp(tsstopresp)); @@ -154,11 +155,11 @@ public void testROS2_RosServiceCallTwice() throws InterruptedException { tsstartresp = clientSync.getTSResp(); tsstopresp = tsstartresp; System.out.println("Service situation - req:"+TimeStamp.getStringTimeStamp(tsstartreq)+" resp:"+TimeStamp.getStringTimeStamp(tsstartresp)); - while (tsstartreq == tsstopreq || tsstartresp == tsstopresp ) { + while (tsstartreq == tsstopreq || tsstartresp == tsstopresp || tsstopresp <= tsstopreq ) { tsstopresp = clientSync.getTSResp(); tsstopreq = clientSync.getTSReq(); System.out.println("tsstartreq: "+TimeStamp.getStringTimeStamp(tsstartreq)+" tsstopreq: "+TimeStamp.getStringTimeStamp(tsstopreq)); - System.out.println("tsstartresp: "+TimeStamp.getStringTimeStamp(tsstartresp)+" tsstopreq: "+TimeStamp.getStringTimeStamp(tsstopresp)); + System.out.println("tsstartresp: "+TimeStamp.getStringTimeStamp(tsstartresp)+" tsstopresp: "+TimeStamp.getStringTimeStamp(tsstopresp)); System.out.println("motorMemory: "+TimeStamp.getStringTimeStamp(motorMemory.getTimestamp())); Thread.sleep(100); } From 5a2d96ef742b09be94167616a820f15d0536c92a Mon Sep 17 00:00:00 2001 From: rgudwin Date: Thu, 9 Oct 2025 16:06:29 -0300 Subject: [PATCH 81/89] Fixing test code --- .../br/unicamp/meca/mind/MecaMindTest.java | 10 ++-- .../meca/mind/action/TestActivityCodelet.java | 2 +- .../tracking/testActivityTrackingCodelet.java | 2 +- .../meca/models/ActionSequencePlanTest.java | 2 +- .../unicamp/meca/models/ActionStepTester.java | 2 +- .../rosservice/ROS2_RosServiceClientTest.java | 58 ++++++++++++++----- .../rosservice/RosServiceClientTest.java | 10 ++-- 7 files changed, 56 insertions(+), 30 deletions(-) diff --git a/src/test/java/br/unicamp/meca/mind/MecaMindTest.java b/src/test/java/br/unicamp/meca/mind/MecaMindTest.java index 2662225..f9bc024 100644 --- a/src/test/java/br/unicamp/meca/mind/MecaMindTest.java +++ b/src/test/java/br/unicamp/meca/mind/MecaMindTest.java @@ -9,9 +9,7 @@ import java.util.HashMap; import java.util.List; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.Test; import br.unicamp.cst.core.entities.Codelet; import br.unicamp.cst.core.entities.Memory; @@ -38,6 +36,8 @@ import br.unicamp.meca.system1.codelets.MotivationalCodelet; import br.unicamp.meca.system1.codelets.PerceptualCodelet; import br.unicamp.meca.system2.codelets.IPlanningCodelet; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; /** * @author andre @@ -65,7 +65,7 @@ public class MecaMindTest { private static IPlanningCodelet planningCodelet; - @BeforeClass + @BeforeAll public static void setup() throws InterruptedException { mecaMind = new MecaMind("MecaMind"); @@ -156,7 +156,7 @@ public static void setup() throws InterruptedException { } - @AfterClass + @AfterAll public static void tearDown() { mv.setVisible(false); diff --git a/src/test/java/br/unicamp/meca/mind/action/TestActivityCodelet.java b/src/test/java/br/unicamp/meca/mind/action/TestActivityCodelet.java index 51a724c..2ac06f3 100644 --- a/src/test/java/br/unicamp/meca/mind/action/TestActivityCodelet.java +++ b/src/test/java/br/unicamp/meca/mind/action/TestActivityCodelet.java @@ -20,7 +20,7 @@ import br.unicamp.meca.system1.codelets.SensoryCodelet; import java.util.ArrayList; import static org.junit.Assert.assertEquals; -import org.junit.Test; +import org.junit.jupiter.api.Test; /** * diff --git a/src/test/java/br/unicamp/meca/mind/tracking/testActivityTrackingCodelet.java b/src/test/java/br/unicamp/meca/mind/tracking/testActivityTrackingCodelet.java index 135cb4f..6a1e967 100644 --- a/src/test/java/br/unicamp/meca/mind/tracking/testActivityTrackingCodelet.java +++ b/src/test/java/br/unicamp/meca/mind/tracking/testActivityTrackingCodelet.java @@ -16,7 +16,7 @@ import br.unicamp.meca.system1.codelets.ActivityTrackingCodelet; import java.util.ArrayList; import static org.junit.Assert.assertEquals; -import org.junit.Test; +import org.junit.jupiter.api.Test; /** * diff --git a/src/test/java/br/unicamp/meca/models/ActionSequencePlanTest.java b/src/test/java/br/unicamp/meca/models/ActionSequencePlanTest.java index 63c876e..4b3f4e4 100644 --- a/src/test/java/br/unicamp/meca/models/ActionSequencePlanTest.java +++ b/src/test/java/br/unicamp/meca/models/ActionSequencePlanTest.java @@ -5,7 +5,7 @@ import static org.junit.Assert.assertEquals; -import org.junit.Test; +import org.junit.jupiter.api.Test; /** * @author andre diff --git a/src/test/java/br/unicamp/meca/models/ActionStepTester.java b/src/test/java/br/unicamp/meca/models/ActionStepTester.java index aae2313..0f4fde7 100644 --- a/src/test/java/br/unicamp/meca/models/ActionStepTester.java +++ b/src/test/java/br/unicamp/meca/models/ActionStepTester.java @@ -5,7 +5,7 @@ */ package br.unicamp.meca.models; import static org.junit.Assert.assertEquals; -import org.junit.Test; +import org.junit.jupiter.api.Test; /** * diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_RosServiceClientTest.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_RosServiceClientTest.java index 6bf2bbd..7cd7549 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_RosServiceClientTest.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_RosServiceClientTest.java @@ -10,10 +10,6 @@ //import br.unicamp.cst.bindings.ros2java.AddTwoIntsServiceClientSyncRos2; //import br.unicamp.cst.bindings.ros2java.AddTwoIntsServiceProvider; -import troca_ros.AddTwoIntsResponseMessage; - -import org.junit.AfterClass; -import org.junit.BeforeClass; import java.util.ArrayList; @@ -21,6 +17,8 @@ import java.util.logging.Level; import java.util.logging.Logger; import static org.junit.Assert.assertEquals; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; //import static org.junit.Assert.assertEquals; import org.junit.jupiter.api.Test; @@ -40,13 +38,13 @@ private static void SilenceLoggers() { Logger.getLogger("id.jros2client").setLevel(Level.OFF); } - @BeforeClass + @BeforeAll public static void setup() { mecaMind = new MecaMind("ROS2_RosServiceClientTest"); Logger.getLogger("id.jros2client").setLevel(Level.OFF); } - @AfterClass + @AfterAll public static void cleanup() { if (mecaMind != null) mecaMind.shutDown(); } @@ -64,7 +62,8 @@ public void testROS2_RosServiceCallOnce() throws InterruptedException { //Memory memory = mecaMind.createMemoryObject("add_two_ints"); // Instantiate ROS2 synchronous client - AddTwoIntsServiceClientSyncRos2 clientSync = new AddTwoIntsServiceClientSyncRos2("add_two_ints"); + //AddTwoIntsServiceClientSyncRos2 clientSync = new AddTwoIntsServiceClientSyncRos2("add_two_ints"); + ROS2_AddTwoIntServiceClient clientSync = new ROS2_AddTwoIntServiceClient("add_two_ints"); //clientSync.start(); // Insert client codelet in mind (for consistency) @@ -74,7 +73,7 @@ public void testROS2_RosServiceCallOnce() throws InterruptedException { mecaMind.mountMecaMind(); mecaMind.start(); - Thread.sleep(5000); + //Thread.sleep(5000); motorMemory = clientSync.getInput(clientSync.getId()); @@ -84,7 +83,25 @@ public void testROS2_RosServiceCallOnce() throws InterruptedException { motorMemory.setI(numsToSum); System.out.println("Nums to sum were changed to {2,3}"); - Thread.sleep(2000); + //Thread.sleep(2000); + long tsstartreq = System.currentTimeMillis(); //clientSync.getTSReq(); + long tsstopreq = tsstartreq; + long tsstartresp = System.currentTimeMillis(); //clientSync.getTSResp(); + long tsstopresp = tsstartresp; + int id = motorMemory.setI(numsToSum); + // At this point, motorMemory has 1 internal MemoryObject and id should be 0 + System.out.println("id: "+id); + System.out.println("\n\nNums to sum were changed to {2,3} at "+TimeStamp.getStringTimeStamp(motorMemory.getTimestamp())); + System.out.println("Service situation - req:"+TimeStamp.getStringTimeStamp(tsstartreq)+" resp:"+TimeStamp.getStringTimeStamp(tsstartresp)); + while (tsstartreq == tsstopreq || tsstartresp == tsstopresp || tsstopresp <= tsstopreq ) { + tsstopresp = clientSync.getTSResp(); + tsstopreq = clientSync.getTSReq(); + //System.out.println("startreq: "+TimeStamp.getStringTimeStamp(tsstartreq)+" stopreq: "+TimeStamp.getStringTimeStamp(tsstopreq)); + //System.out.println("startresp: "+TimeStamp.getStringTimeStamp(tsstartresp)+" stopresp: "+TimeStamp.getStringTimeStamp(tsstopresp)); + Thread.sleep(100); + } + System.out.println("Finished process - req:"+TimeStamp.getStringTimeStamp(tsstopreq)+" resp:"+TimeStamp.getStringTimeStamp(tsstopresp)); + System.out.println("I took "+TimeStamp.getStringTimeStamp(tsstopresp-tsstartreq,"mm:ss.SSS")+ " s to attend the service request !!"); assertEquals(expectedSum, clientSync.getSum()); @@ -93,6 +110,10 @@ public void testROS2_RosServiceCallOnce() throws InterruptedException { serviceProvider.stop(); mecaMind.shutDown(); } + + public String cvr(long t) { + return TimeStamp.getStringTimeStamp(t,"hh:mm:ss.SSS"); + } @Test public void testROS2_RosServiceCallTwice() throws InterruptedException { @@ -135,12 +156,14 @@ public void testROS2_RosServiceCallTwice() throws InterruptedException { while (tsstartreq == tsstopreq || tsstartresp == tsstopresp || tsstopresp <= tsstopreq ) { tsstopresp = clientSync.getTSResp(); tsstopreq = clientSync.getTSReq(); - System.out.println("startreq: "+TimeStamp.getStringTimeStamp(tsstartreq)+" stopreq: "+TimeStamp.getStringTimeStamp(tsstopreq)); - System.out.println("startresp: "+TimeStamp.getStringTimeStamp(tsstartresp)+" stopresp: "+TimeStamp.getStringTimeStamp(tsstopresp)); + System.out.print("."); + //System.out.println("req: "+cvr(tsstartreq)+" "+cvr(tsstopreq)); + //System.out.println("resp: "+cvr(tsstartresp)+" "+cvr(tsstopresp)); Thread.sleep(100); } - System.out.println("Finished process - req:"+TimeStamp.getStringTimeStamp(tsstopreq)+" resp:"+TimeStamp.getStringTimeStamp(tsstopresp)); + System.out.println("\nFinished process - req:"+TimeStamp.getStringTimeStamp(tsstopreq)+" resp:"+TimeStamp.getStringTimeStamp(tsstopresp)); //Thread.sleep(5000); + System.out.println("I took "+TimeStamp.getStringTimeStamp(tsstopresp-tsstartreq,"mm:ss.SSS")+ " s to attend the service request !!"); assertEquals(expectedSum, clientSync.getSum()); @@ -158,12 +181,15 @@ public void testROS2_RosServiceCallTwice() throws InterruptedException { while (tsstartreq == tsstopreq || tsstartresp == tsstopresp || tsstopresp <= tsstopreq ) { tsstopresp = clientSync.getTSResp(); tsstopreq = clientSync.getTSReq(); - System.out.println("tsstartreq: "+TimeStamp.getStringTimeStamp(tsstartreq)+" tsstopreq: "+TimeStamp.getStringTimeStamp(tsstopreq)); - System.out.println("tsstartresp: "+TimeStamp.getStringTimeStamp(tsstartresp)+" tsstopresp: "+TimeStamp.getStringTimeStamp(tsstopresp)); - System.out.println("motorMemory: "+TimeStamp.getStringTimeStamp(motorMemory.getTimestamp())); + //System.out.println("tsstartreq: "+TimeStamp.getStringTimeStamp(tsstartreq)+" tsstopreq: "+TimeStamp.getStringTimeStamp(tsstopreq)); + //System.out.println("tsstartresp: "+TimeStamp.getStringTimeStamp(tsstartresp)+" tsstopresp: "+TimeStamp.getStringTimeStamp(tsstopresp)); + //System.out.println("motorMemory: "+TimeStamp.getStringTimeStamp(motorMemory.getTimestamp())); + System.out.print("."); Thread.sleep(100); } - System.out.println("Finished process - req:"+TimeStamp.getStringTimeStamp(tsstopreq)+" resp"+TimeStamp.getStringTimeStamp(tsstopresp)); + System.out.println("\nFinished process - req:"+TimeStamp.getStringTimeStamp(tsstopreq)+" resp:"+TimeStamp.getStringTimeStamp(tsstopresp)); + System.out.println("I took "+TimeStamp.getStringTimeStamp(tsstopresp-tsstartreq,"mm:ss.SSS")+ " s to attend the service request !!"); + assertEquals(expectedSum, clientSync.getSum()); serviceProvider.stop(); diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/RosServiceClientTest.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/RosServiceClientTest.java index 363326a..532aa32 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/RosServiceClientTest.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/RosServiceClientTest.java @@ -10,9 +10,7 @@ import java.util.ArrayList; import java.util.List; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.ros.RosCore; import org.ros.node.DefaultNodeMainExecutor; import org.ros.node.NodeConfiguration; @@ -25,6 +23,8 @@ import br.unicamp.meca.system1.codelets.IMotorCodelet; import java.util.logging.Level; import java.util.logging.Logger; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; import org.slf4j.LoggerFactory; /** @@ -36,14 +36,14 @@ public class RosServiceClientTest { private static RosCore rosCore; private volatile Memory motorMemory; - @BeforeClass + @BeforeAll public static void beforeAllTestMethods() { rosCore = RosCore.newPublic("127.0.0.1",11311); rosCore.start(); try{Thread.sleep(1000);} catch(Exception e){e.printStackTrace();} } - @AfterClass + @AfterAll public static void afterAllTestMethods() { rosCore.shutdown(); } From df9e9d4ed67e91c84e7b6d0be4164d78a78e3854 Mon Sep 17 00:00:00 2001 From: rgudwin Date: Tue, 14 Oct 2025 16:02:49 -0300 Subject: [PATCH 82/89] Trying to solve a bug in closing connections --- ...t.java => AddTwoIntROS1ServiceClient.java} | 4 +- ...java => AddTwoIntROS1ServiceProvider.java} | 2 +- ...t.java => AddTwoIntROS2ServiceClient.java} | 15 +++- ...ava => AddTwoIntsROS2ServiceProvider.java} | 7 +- .../AddTwoIntsServiceClientSyncRos2.java | 85 ------------------- ...tTest.java => ROS1_ServiceClientTest.java} | 10 +-- .../rosservice/ROS2_AddTwoIntService.java | 64 -------------- ...tTest.java => ROS2_ServiceClientTest.java} | 30 ++++--- 8 files changed, 46 insertions(+), 171 deletions(-) rename src/test/java/br/unicamp/meca/system1/codelets/rosservice/{AddTwoIntServiceClient.java => AddTwoIntROS1ServiceClient.java} (91%) rename src/test/java/br/unicamp/meca/system1/codelets/rosservice/{AddTwoIntService.java => AddTwoIntROS1ServiceProvider.java} (92%) rename src/test/java/br/unicamp/meca/system1/codelets/rosservice/{ROS2_AddTwoIntServiceClient.java => AddTwoIntROS2ServiceClient.java} (83%) rename src/test/java/br/unicamp/meca/system1/codelets/rosservice/{AddTwoIntsServiceProvider.java => AddTwoIntsROS2ServiceProvider.java} (91%) delete mode 100644 src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntsServiceClientSyncRos2.java rename src/test/java/br/unicamp/meca/system1/codelets/rosservice/{RosServiceClientTest.java => ROS1_ServiceClientTest.java} (93%) delete mode 100644 src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_AddTwoIntService.java rename src/test/java/br/unicamp/meca/system1/codelets/rosservice/{ROS2_RosServiceClientTest.java => ROS2_ServiceClientTest.java} (88%) diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntServiceClient.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntROS1ServiceClient.java similarity index 91% rename from src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntServiceClient.java rename to src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntROS1ServiceClient.java index 088826c..a0ccea2 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntServiceClient.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntROS1ServiceClient.java @@ -15,13 +15,13 @@ * @author andre * */ -public class AddTwoIntServiceClient extends RosServiceClientMotorCodelet { +public class AddTwoIntROS1ServiceClient extends RosServiceClientMotorCodelet { private volatile Integer a,b; private volatile Integer sum; private volatile long tsreq=0, tsresp=0; - public AddTwoIntServiceClient(String host, URI masterURI) { + public AddTwoIntROS1ServiceClient(String host, URI masterURI) { super("AddTwoIntServiceClient", "add_two_ints", rosjava_test_msgs.AddTwoInts._TYPE, host, masterURI); } diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntService.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntROS1ServiceProvider.java similarity index 92% rename from src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntService.java rename to src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntROS1ServiceProvider.java index 59c1e34..6a91bb2 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntService.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntROS1ServiceProvider.java @@ -12,7 +12,7 @@ * @author andre * */ -public class AddTwoIntService extends AbstractNodeMain { +public class AddTwoIntROS1ServiceProvider extends AbstractNodeMain { @Override public GraphName getDefaultNodeName() { diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_AddTwoIntServiceClient.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntROS2ServiceClient.java similarity index 83% rename from src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_AddTwoIntServiceClient.java rename to src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntROS2ServiceClient.java index 5026f04..c4b0861 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_AddTwoIntServiceClient.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntROS2ServiceClient.java @@ -14,13 +14,14 @@ * @author jrborelli * */ -public class ROS2_AddTwoIntServiceClient extends Ros2ServiceClientMotorCodelet { +public class AddTwoIntROS2ServiceClient extends Ros2ServiceClientMotorCodelet { private volatile Integer a, b; private volatile Integer sum; private volatile long tsReq = 0, tsResp = 0; + public boolean processing = false; - public ROS2_AddTwoIntServiceClient(String serviceName) { + public AddTwoIntROS2ServiceClient(String serviceName) { super(serviceName, serviceName, new AddTwoIntsServiceDefinition()); } @@ -31,6 +32,7 @@ protected AddTwoIntsRequestMessage createNewRequest() { @Override protected boolean formatServiceRequest(Memory motorMemory, AddTwoIntsRequestMessage request) { + processing = true; //System.out.println("Request"); if (motorMemory == null || motorMemory.getI() == null) { if (motorMemory == null) System.out.println("motorMemory is null"); @@ -61,6 +63,7 @@ protected void processServiceResponse(AddTwoIntsResponseMessage response) { tsResp = System.currentTimeMillis(); System.out.println("RESPONSE Sum=" + sum + " at " + TimeStamp.getStringTimeStamp(tsResp)); } + processing = false; } public synchronized Integer getSum() { @@ -74,4 +77,12 @@ public synchronized long getTSReq() { public synchronized long getTSResp() { return tsResp; } + + @Override + public void stop() { + while(processing) { + try{Thread.sleep(100);} catch(Exception e){} + } + super.stop(); + } } \ No newline at end of file diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntsServiceProvider.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntsROS2ServiceProvider.java similarity index 91% rename from src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntsServiceProvider.java rename to src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntsROS2ServiceProvider.java index e67f72d..7a793fa 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntsServiceProvider.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntsROS2ServiceProvider.java @@ -14,7 +14,7 @@ * @author jrborelli */ -public class AddTwoIntsServiceProvider implements Runnable { +public class AddTwoIntsROS2ServiceProvider implements Runnable { volatile boolean stopflag = false; private Thread thread; @@ -23,8 +23,9 @@ public class AddTwoIntsServiceProvider implements Runnable { ServiceHandler proc; JRos2Client client; JRos2Service service; + public boolean running = false; - public AddTwoIntsServiceProvider() { + public AddTwoIntsROS2ServiceProvider() { proc = new ServiceHandler<>() { @Override public AddTwoIntsResponseMessage execute(AddTwoIntsRequestMessage request) { @@ -39,6 +40,7 @@ public AddTwoIntsResponseMessage execute(AddTwoIntsRequestMessage request) { @Override public void run() { + running = true; clientFactory = new JRos2ClientFactory(); serviceClientFactory = new JRos2ServicesFactory(); @@ -52,6 +54,7 @@ public void run() { service.close(); client.close(); System.out.println("Service finished ..."); + running = false; } public void start() { diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntsServiceClientSyncRos2.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntsServiceClientSyncRos2.java deleted file mode 100644 index 8920c6e..0000000 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntsServiceClientSyncRos2.java +++ /dev/null @@ -1,85 +0,0 @@ - -package br.unicamp.meca.system1.codelets.rosservice; - -import troca_ros.AddTwoIntsRequestMessage; -import troca_ros.AddTwoIntsResponseMessage; -import troca_ros.AddTwoIntsServiceDefinition; -import br.unicamp.meca.system1.codelets.Ros2ServiceClientMotorCodelet; -import br.unicamp.cst.core.entities.Memory; -import br.unicamp.cst.core.entities.MemoryObject; - -/** - * - * @author jrborelli - */ - - -public class AddTwoIntsServiceClientSyncRos2 extends Ros2ServiceClientMotorCodelet { - - private volatile Integer a,b; - private volatile Integer sum; - private volatile long tsReq = 0, tsResp = 0; - - public AddTwoIntsServiceClientSyncRos2(String serviceName) { - super("AddTwoIntsServiceClientSyncRos2", serviceName, new AddTwoIntsServiceDefinition()); - } - - /* - @Override - public boolean formatServiceRequest(Memory memory, AddTwoIntsRequestMessage requestMessage) { - Object[] args = (Object[]) memory.getI(); // or however you extract the inputs - requestMessage.withA((Long) args[0]).withB((Long) args[1]); - - return true; // return value if the superclass expects boolean - } */ - - - @Override //exemplo: - protected boolean formatServiceRequest(Memory memory, AddTwoIntsRequestMessage request) { - Integer[] inputs = (Integer[]) memory.getI(); // example cast - if (inputs == null || inputs.length < 2) return false; - a = inputs[0]; - b = inputs[1]; - request.withA(a); - request.withB(b); - tsReq = System.currentTimeMillis(); - return true; - } - - - @Override - protected AddTwoIntsRequestMessage createNewRequest() { - return new AddTwoIntsRequestMessage(); - } - - @Override - public void processServiceResponse(AddTwoIntsResponseMessage response) { - // For synchronous calls, you may leave it empty - // or handle logging if needed - } - - - public AddTwoIntsResponseMessage callService(Integer[] inputs) { - sum = inputs[0]+inputs[1]; - tsResp = System.currentTimeMillis(); - AddTwoIntsResponseMessage response = new AddTwoIntsResponseMessage(sum); - processServiceResponse(response); - return response; -} - - /** - * @return the sum - */ - public synchronized Integer getSum() { - return sum; - } - - public synchronized long getTSReq() { - return tsReq; - } - - public synchronized long getTSResp() { - return tsResp; - } - -} diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/RosServiceClientTest.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS1_ServiceClientTest.java similarity index 93% rename from src/test/java/br/unicamp/meca/system1/codelets/rosservice/RosServiceClientTest.java rename to src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS1_ServiceClientTest.java index 532aa32..ce5373d 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/RosServiceClientTest.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS1_ServiceClientTest.java @@ -31,7 +31,7 @@ * @author andre * */ -public class RosServiceClientTest { +public class ROS1_ServiceClientTest { private static RosCore rosCore; private volatile Memory motorMemory; @@ -58,7 +58,7 @@ public void SilenceLoggers() { @Test public void testRosService() throws URISyntaxException, InterruptedException { - AddTwoIntService addTwoIntService = new AddTwoIntService(); + AddTwoIntROS1ServiceProvider addTwoIntService = new AddTwoIntROS1ServiceProvider(); NodeMainExecutor nodeMainExecutor = DefaultNodeMainExecutor.newDefault(); NodeConfiguration nodeConfiguration = NodeConfiguration.newPublic("127.0.0.1",new URI("http://127.0.0.1:11311")); nodeMainExecutor.execute(addTwoIntService, nodeConfiguration); @@ -70,7 +70,7 @@ public void testRosService() throws URISyntaxException, InterruptedException { List motorCodelets = new ArrayList<>(); - AddTwoIntServiceClient addTwoIntServiceClient = new AddTwoIntServiceClient("127.0.0.1",new URI("http://127.0.0.1:11311")); + AddTwoIntROS1ServiceClient addTwoIntServiceClient = new AddTwoIntROS1ServiceClient("127.0.0.1",new URI("http://127.0.0.1:11311")); motorCodelets.add(addTwoIntServiceClient); mecaMind.setIMotorCodelets(motorCodelets); @@ -101,7 +101,7 @@ public void testRosService() throws URISyntaxException, InterruptedException { public void testRosServiceCallTwice() throws URISyntaxException, InterruptedException { SilenceLoggers(); - AddTwoIntService addTwoIntService = new AddTwoIntService(); + AddTwoIntROS1ServiceProvider addTwoIntService = new AddTwoIntROS1ServiceProvider(); NodeMainExecutor nodeMainExecutor = DefaultNodeMainExecutor.newDefault(); NodeConfiguration nodeConfiguration = NodeConfiguration.newPublic("127.0.0.1",new URI("http://127.0.0.1:11311")); nodeMainExecutor.execute(addTwoIntService, nodeConfiguration); @@ -112,7 +112,7 @@ public void testRosServiceCallTwice() throws URISyntaxException, InterruptedExce List motorCodelets = new ArrayList<>(); - AddTwoIntServiceClient addTwoIntServiceClient = new AddTwoIntServiceClient("127.0.0.1",new URI("http://127.0.0.1:11311")); + AddTwoIntROS1ServiceClient addTwoIntServiceClient = new AddTwoIntROS1ServiceClient("127.0.0.1",new URI("http://127.0.0.1:11311")); motorCodelets.add(addTwoIntServiceClient); mecaMind.setIMotorCodelets(motorCodelets); diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_AddTwoIntService.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_AddTwoIntService.java deleted file mode 100644 index 67d724b..0000000 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_AddTwoIntService.java +++ /dev/null @@ -1,64 +0,0 @@ - -package br.unicamp.meca.system1.codelets.rosservice; - -import pinorobotics.jros2services.JRos2Service; -import pinorobotics.jros2services.JRos2ServicesFactory; -import pinorobotics.jros2services.ServiceHandler; -import id.jros2client.JRos2Client; -import id.jros2client.JRos2ClientFactory; -import troca_ros.AddTwoIntsRequestMessage; -import troca_ros.AddTwoIntsResponseMessage; -import troca_ros.AddTwoIntsServiceDefinition; - -/** - * @author jrborelli - * - */ -public class ROS2_AddTwoIntService implements Runnable { - - private volatile boolean stopflag = false; - private Thread thread; - - private JRos2Client client; - private JRos2Service service; - - public ROS2_AddTwoIntService() { - } - - @Override - public void run() { - // Create client and service factory - JRos2ClientFactory clientFactory = new JRos2ClientFactory(); - JRos2ServicesFactory serviceFactory = new JRos2ServicesFactory(); - - client = clientFactory.createClient(); - - // Define service handler - ServiceHandler handler = - request -> new AddTwoIntsResponseMessage(request.a + request.b); - - service = serviceFactory.createService(client, new AddTwoIntsServiceDefinition(), "add_two_ints", handler); - service.start(); - - System.out.println("Service started..."); - - while (!stopflag) { - // keep running - } - - service.close(); - client.close(); - System.out.println("Service stopped..."); - } - - public void start() { - if (thread == null) { - thread = new Thread(this); - thread.start(); - } - } - - public void stop() { - stopflag = true; - } -} \ No newline at end of file diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_RosServiceClientTest.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_ServiceClientTest.java similarity index 88% rename from src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_RosServiceClientTest.java rename to src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_ServiceClientTest.java index 7cd7549..cdc5f79 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_RosServiceClientTest.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_ServiceClientTest.java @@ -9,7 +9,7 @@ import br.unicamp.meca.system1.codelets.IMotorCodelet; //import br.unicamp.cst.bindings.ros2java.AddTwoIntsServiceClientSyncRos2; -//import br.unicamp.cst.bindings.ros2java.AddTwoIntsServiceProvider; +//import br.unicamp.cst.bindings.ros2java.AddTwoIntsROS2ServiceProvider; import java.util.ArrayList; @@ -27,9 +27,9 @@ * * @author jrborelli */ -public class ROS2_RosServiceClientTest { +public class ROS2_ServiceClientTest { - private static final Logger LOGGER = Logger.getLogger(ROS2_RosServiceClientTest.class.getName()); + private static final Logger LOGGER = Logger.getLogger(ROS2_ServiceClientTest.class.getName()); private static MecaMind mecaMind; private volatile Memory motorMemory; @@ -51,10 +51,11 @@ public static void cleanup() { @Test public void testROS2_RosServiceCallOnce() throws InterruptedException { + System.out.println("\nStarting the RosServiceCallOnce test"); SilenceLoggers(); setup(); // Start ROS2 service provider - AddTwoIntsServiceProvider serviceProvider = new AddTwoIntsServiceProvider(); + AddTwoIntsROS2ServiceProvider serviceProvider = new AddTwoIntsROS2ServiceProvider(); serviceProvider.start(); Thread.sleep(500); // give service time to start @@ -63,7 +64,7 @@ public void testROS2_RosServiceCallOnce() throws InterruptedException { // Instantiate ROS2 synchronous client //AddTwoIntsServiceClientSyncRos2 clientSync = new AddTwoIntsServiceClientSyncRos2("add_two_ints"); - ROS2_AddTwoIntServiceClient clientSync = new ROS2_AddTwoIntServiceClient("add_two_ints"); + AddTwoIntROS2ServiceClient clientSync = new AddTwoIntROS2ServiceClient("add_two_ints"); //clientSync.start(); // Insert client codelet in mind (for consistency) @@ -107,8 +108,12 @@ public void testROS2_RosServiceCallOnce() throws InterruptedException { // Cleanup //clientSync.stop(); - serviceProvider.stop(); mecaMind.shutDown(); + //Thread.sleep(5000); + clientSync.stop(); + serviceProvider.stop(); + while (serviceProvider.running) Thread.sleep(100); + System.out.println("The test was finished!"); } public String cvr(long t) { @@ -117,16 +122,17 @@ public String cvr(long t) { @Test public void testROS2_RosServiceCallTwice() throws InterruptedException { + System.out.println("\nStarting the RosServiceCallTwice test"); SilenceLoggers(); setup(); // Start ROS2 service provider - AddTwoIntsServiceProvider serviceProvider = new AddTwoIntsServiceProvider(); + AddTwoIntsROS2ServiceProvider serviceProvider = new AddTwoIntsROS2ServiceProvider(); serviceProvider.start(); Thread.sleep(500); //Memory memory = mecaMind.createMemoryObject("add_two_ints"); - ROS2_AddTwoIntServiceClient clientSync = new ROS2_AddTwoIntServiceClient("add_two_ints"); + AddTwoIntROS2ServiceClient clientSync = new AddTwoIntROS2ServiceClient("add_two_ints"); //clientSync.start(); List motorCodelets = new ArrayList<>(); @@ -191,8 +197,12 @@ public void testROS2_RosServiceCallTwice() throws InterruptedException { System.out.println("I took "+TimeStamp.getStringTimeStamp(tsstopresp-tsstartreq,"mm:ss.SSS")+ " s to attend the service request !!"); assertEquals(expectedSum, clientSync.getSum()); - - serviceProvider.stop(); mecaMind.shutDown(); + clientSync.stop(); + //Thread.sleep(5000); + serviceProvider.stop(); + while (serviceProvider.running) Thread.sleep(100); + //Thread.sleep(5000); + System.out.println("The test was finished!"); } } \ No newline at end of file From 2f6604ff0d736a791e5e700f9f877cfbef3f0295 Mon Sep 17 00:00:00 2001 From: Jose Renato Borelli Date: Tue, 21 Oct 2025 14:38:55 -0300 Subject: [PATCH 83/89] MECA - ROS2 - first version - new tests --- build.gradle | 4 +- .../Ros2TopicPublisherMotorCodelet.java | 2 +- .../Ros2TopicSubscriberSensoryCodelet.java | 2 +- .../rosservice/ROS1_ServiceClientTest.java | 5 +- .../rosservice/ROS2_ServiceClientTest.java | 6 +- .../ROS2_RosTopicPublisherSubscriberTest.java | 203 +++++++++++++++++- .../RosTopicPublisherSubscriberTest.java | 14 +- 7 files changed, 211 insertions(+), 25 deletions(-) diff --git a/build.gradle b/build.gradle index e04a3ad..06501eb 100644 --- a/build.gradle +++ b/build.gradle @@ -36,12 +36,12 @@ configurations { } dependencies { - //implementation files('../cst-bindings/build/libs/cst-bindings.jar') + implementation files('../cst-bindings/build/libs/cst-bindings.jar') //RESOLVEU -> estava comentadado //implementation project(':cst-bindings') // CST Desktop API //api('com.github.CST-Group:cst-desktop:1.1.0') api(':cst-desktop:1.1.1-full') - // CST Bindings (flat JAR) + //CST Bindings (flat JAR) //api name: 'cst-bindings', ext: 'jar' // JUnit and testing diff --git a/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicPublisherMotorCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicPublisherMotorCodelet.java index 76271eb..3b5035e 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicPublisherMotorCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicPublisherMotorCodelet.java @@ -27,7 +27,7 @@ public abstract class Ros2TopicPublisherMotorCodelet */ public Ros2TopicPublisherMotorCodelet(String id, String topic, Class messageType) { super(topic, messageType); - this.id = id; + this.id = topic; } /** diff --git a/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicSubscriberSensoryCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicSubscriberSensoryCodelet.java index 489d554..f95d31a 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicSubscriberSensoryCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicSubscriberSensoryCodelet.java @@ -26,7 +26,7 @@ public abstract class Ros2TopicSubscriberSensoryCodelet */ public Ros2TopicSubscriberSensoryCodelet(String id, String topic, Class messageType) { super(topic, messageType); - this.id = id; + this.id = topic; } /** diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS1_ServiceClientTest.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS1_ServiceClientTest.java index ce5373d..49f7d89 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS1_ServiceClientTest.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS1_ServiceClientTest.java @@ -3,14 +3,13 @@ */ package br.unicamp.meca.system1.codelets.rosservice; -import static org.junit.Assert.assertEquals; +//import static org.junit.Assert.assertEquals; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; -import org.junit.jupiter.api.Test; import org.ros.RosCore; import org.ros.node.DefaultNodeMainExecutor; import org.ros.node.NodeConfiguration; @@ -23,6 +22,8 @@ import br.unicamp.meca.system1.codelets.IMotorCodelet; import java.util.logging.Level; import java.util.logging.Logger; +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.slf4j.LoggerFactory; diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_ServiceClientTest.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_ServiceClientTest.java index cdc5f79..c7ba578 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_ServiceClientTest.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_ServiceClientTest.java @@ -8,7 +8,7 @@ import br.unicamp.meca.mind.MecaMind; import br.unicamp.meca.system1.codelets.IMotorCodelet; -//import br.unicamp.cst.bindings.ros2java.AddTwoIntsServiceClientSyncRos2; +//import br.unicamp.cst.bindings.ros2java; //import br.unicamp.cst.bindings.ros2java.AddTwoIntsROS2ServiceProvider; @@ -16,10 +16,10 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import static org.junit.Assert.assertEquals; +//import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; -//import static org.junit.Assert.assertEquals; import org.junit.jupiter.api.Test; /** diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_RosTopicPublisherSubscriberTest.java b/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_RosTopicPublisherSubscriberTest.java index e3ae2de..ee5cf3d 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_RosTopicPublisherSubscriberTest.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_RosTopicPublisherSubscriberTest.java @@ -1,13 +1,13 @@ package br.unicamp.meca.system1.codelets.rostopic; -import static org.junit.Assert.assertEquals; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import br.unicamp.cst.core.entities.Memory; +import br.unicamp.cst.core.entities.MemoryObject; import br.unicamp.meca.mind.MecaMind; import br.unicamp.meca.system1.codelets.IMotorCodelet; import br.unicamp.meca.system1.codelets.ISensoryCodelet; @@ -15,22 +15,200 @@ import java.util.ArrayList; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + /** * ROS2 version of the MECA ROS1 Publisher-Subscriber test * * @author jrborelli */ + +import java.time.Duration; +import java.time.Instant; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; + + +/** + * Fully asynchronous ROS2 Publisher-Subscriber test using CompletableFuture. + * Reacts immediately when the message arrives. + * + * Author: jrborelli + */ + +public class ROS2_RosTopicPublisherSubscriberTest { + + private static final Logger LOGGER = Logger.getLogger(ROS2_RosTopicPublisherSubscriberTest.class.getName()); + private static MecaMind mecaMind; + + @BeforeAll + public static void setup() { + LOGGER.info("Setting up MecaMind for ROS2 Publisher/Subscriber test..."); + // optionally silence noisy loggers here if you want: + // Logger.getLogger("pinorobotics.rtpstalk").setLevel(Level.OFF); + // Logger.getLogger("id.jros2client").setLevel(Level.OFF); + mecaMind = new MecaMind("ROS2_RosTopicPublisherSubscriber"); + } + + @AfterAll + public static void teardown() { + LOGGER.info("Tearing down MecaMind..."); + if (mecaMind != null) { + mecaMind.shutDown(); + } + } + + @Test + public void testChatterTopicIntegration() throws Exception { + // --- Create specialized codelets --- + ROS2_ChatterTopicPublisher publisherCodelet = new ROS2_ChatterTopicPublisher("chatter"); + ROS2_ChatterTopicSubscriber subscriberCodelet = new ROS2_ChatterTopicSubscriber("chatter"); + LOGGER.log(Level.INFO,"#############" + subscriberCodelet.getId()); + // --- Create Memory objects named exactly as the ROS topic --- + MemoryObject topicMemoryForPublisher = new MemoryObject(); + topicMemoryForPublisher.setName("chatter"); // IMPORTANT: name == topic + + MemoryObject topicMemoryForSubscriber = new MemoryObject(); + topicMemoryForSubscriber.setName("chatter"); // IMPORTANT: name == topic + + MemoryObject topicMemoryForPublisherNNN = new MemoryObject(); //NOVO + topicMemoryForPublisherNNN.setName("NNN"); // IMPORTANT: name == topic //NOVO + + //MemoryObject topicMemoryForSubscriberNNN = new MemoryObject(); //NOVO + //topicMemoryForSubscriberNNN.setName("NNN"); // IMPORTANT: name == topic //NOVO + + // --- Attach the topic-named memories to the codelets BEFORE mounting --- + // This ensures that RosTopicSubscriberCodelet.accessMemoryObjects() + // (which looks up outputs by topic name) will find the memory immediately. + publisherCodelet.addInput(topicMemoryForPublisher); + publisherCodelet.addInput(topicMemoryForPublisherNNN); + subscriberCodelet.addOutput(topicMemoryForSubscriber); + //subscriberCodelet.addOutput(topicMemoryForSubscriberNNN);//NOVO + + // --- Register codelets in the MECA mind lists --- + List motorCodelets = new ArrayList<>(); + motorCodelets.add(publisherCodelet); + + List sensoryCodelets = new ArrayList<>(); + sensoryCodelets.add(subscriberCodelet); + + mecaMind.setIMotorCodelets(motorCodelets); + mecaMind.setISensoryCodelets(sensoryCodelets); + + // --- Mount and start MECA Mind --- + // mountMecaMind will also create its own memories (by codelet ID), + // but we already provided a topic-named memory that the codelets expect. + mecaMind.mountMecaMind(); + mecaMind.start(); + + LOGGER.info("MECA Mind started — waiting for topic bridge..."); + + // --- Send the test message by setting the publisher's memory --- + String messageExpected = "Hello World"; + String messageExpectedNNN = "NNN"; + // set on the memory object we attached to the publisher earlier + topicMemoryForPublisher.setI(messageExpected); + topicMemoryForPublisherNNN.setI(messageExpectedNNN); + + // --- Wait for the subscriber to update the subscriber memory --- + // We poll short intervals, respect total timeout (5s). + final long timeoutMillis = 50000L; + final long pollIntervalMs = 50L; + final long start = System.currentTimeMillis(); + String messageActual = null; + + while (System.currentTimeMillis() - start < timeoutMillis) { + Object val = topicMemoryForSubscriber.getI(); + if (val instanceof String) { + messageActual = (String) val; + // we got a string — break + break; + } + TimeUnit.MILLISECONDS.sleep(pollIntervalMs); + } + + // --- Validate --- + LOGGER.log(Level.INFO, "Expected = \"{0}\", Actual = \"{1}\"", new Object[]{messageExpected, messageActual}); + assertEquals(messageExpected, messageActual); + + // --- Shutdown --- + mecaMind.shutDown(); + } + + @Test + public void testRos2Topics() throws InterruptedException { + + List motorCodelets = new ArrayList<>(); + ROS2_ChatterTopicPublisher chatterTopicPublisher = new ROS2_ChatterTopicPublisher("chatter"); + motorCodelets.add(chatterTopicPublisher); + + List sensoryCodelets = new ArrayList<>(); + ROS2_ChatterTopicSubscriber chatterTopicSubscriber = new ROS2_ChatterTopicSubscriber("chatter"); + sensoryCodelets.add(chatterTopicSubscriber); + + LOGGER.log(Level.INFO,"#############" + chatterTopicSubscriber.getId()); + LOGGER.log(Level.INFO,"#############" + chatterTopicPublisher.getId()); + + mecaMind.setIMotorCodelets(motorCodelets); + mecaMind.setISensoryCodelets(sensoryCodelets); + mecaMind.mountMecaMind(); + + mecaMind.start(); + LOGGER.info("MECA Mind started — waiting for topic bridge..."); + + // Give time for nodes to start + Thread.sleep(1000); + + String messageExpected = "Hello World"; + Memory motorMemory = chatterTopicPublisher.getInput(chatterTopicPublisher.getId()); + ////////////////chatterTopicPublisher.getInput(chatterTopicPublisher.getId()).setI(messageExpected); + ////////////////chatterTopicPublisher.getInput(chatterTopicPublisher.getId()).setName("chatter"); + motorMemory.setI(messageExpected); + motorMemory.setName("chatter"); // NOVO + chatterTopicPublisher.addInput(motorMemory);//NOVO + + // Wait for the message to propagate + Thread.sleep(1000); + + //Memory sensoryMemory2 = chatterTopicSubscriber.getOutput(chatterTopicSubscriber.getId()); + //sensoryMemory2.setName("chatter");//NOVO + //chatterTopicSubscriber.addOutput(sensoryMemory2);//NOVO + + Thread.sleep(10000); + + Memory sensoryMemory = chatterTopicSubscriber.getOutput(chatterTopicSubscriber.getId()); + LOGGER.log(Level.INFO,"#############" + chatterTopicSubscriber.getId()); + //chatterTopicSubscriber.getOutput(chatterTopicSubscriber.getId()).setName("chatter"); + ///////////////Memory sensoryMemory = chatterTopicSubscriber.getOutput("chatterTopicSubscriber"); + String messageActual = (String) sensoryMemory.getI(); + + LOGGER.log(Level.INFO, "Expected = \"{0}\", Actual = \"{1}\"", new Object[]{messageExpected, messageActual}); + assertEquals(messageExpected, messageActual); + + mecaMind.shutDown(); // Already in @AfterAll + } +} + + +/* public class ROS2_RosTopicPublisherSubscriberTest { private static MecaMind mecaMind; + private static final Logger LOGGER = Logger.getLogger(ROS2_RosTopicPublisherSubscriberTest.class.getName()); - @BeforeClass + @BeforeAll public static void beforeAllTestMethods() { + LOGGER.info("Setting up MecaMind for ROS2 Publisher/Subscriber test..."); mecaMind = new MecaMind("ROS2_RosTopicPublisherSubscriber"); } - @AfterClass + @AfterAll public static void afterAllTestMethods() { + LOGGER.info("Tearing down MecaMind..."); if (mecaMind != null) { mecaMind.shutDown(); } @@ -46,12 +224,13 @@ public void testRos2Topics() throws InterruptedException { List sensoryCodelets = new ArrayList<>(); ROS2_ChatterTopicSubscriber chatterTopicSubscriber = new ROS2_ChatterTopicSubscriber("chatter"); sensoryCodelets.add(chatterTopicSubscriber); - + mecaMind.setIMotorCodelets(motorCodelets); mecaMind.setISensoryCodelets(sensoryCodelets); mecaMind.mountMecaMind(); mecaMind.start(); + LOGGER.info("MECA Mind started — waiting for topic bridge..."); // Give time for nodes to start Thread.sleep(1000); @@ -66,8 +245,12 @@ public void testRos2Topics() throws InterruptedException { Memory sensoryMemory = chatterTopicSubscriber.getOutput(chatterTopicSubscriber.getId()); String messageActual = (String) sensoryMemory.getI(); + LOGGER.log(Level.INFO, "Expected = \"{0}\", Actual = \"{1}\"", new Object[]{messageExpected, messageActual}); assertEquals(messageExpected, messageActual); - mecaMind.shutDown(); + mecaMind.shutDown(); // Already in @AfterAll } -} \ No newline at end of file +} + + +*/ \ No newline at end of file diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rostopic/RosTopicPublisherSubscriberTest.java b/src/test/java/br/unicamp/meca/system1/codelets/rostopic/RosTopicPublisherSubscriberTest.java index 731154f..11e9793 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rostopic/RosTopicPublisherSubscriberTest.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rostopic/RosTopicPublisherSubscriberTest.java @@ -3,16 +3,18 @@ */ package br.unicamp.meca.system1.codelets.rostopic; -import static org.junit.Assert.assertEquals; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; +//import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + import org.ros.RosCore; import br.unicamp.cst.core.entities.Memory; @@ -28,14 +30,14 @@ public class RosTopicPublisherSubscriberTest { private static RosCore rosCore; - @BeforeClass + @BeforeAll public static void beforeAllTestMethods() { rosCore = RosCore.newPublic("127.0.0.1",11311); rosCore.start(); try{Thread.sleep(1000);} catch(Exception e){e.printStackTrace();} } - @AfterClass + @AfterAll public static void afterAllTestMethods() { rosCore.shutdown(); } From 4613ff5b2ba7bf06ea2de9b095ea568392d6ae41 Mon Sep 17 00:00:00 2001 From: rgudwin Date: Tue, 21 Oct 2025 16:39:22 -0300 Subject: [PATCH 84/89] Fixing MECA tests --- build.gradle | 2 +- .../Ros2TopicPublisherMotorCodelet.java | 2 +- .../Ros2TopicSubscriberSensoryCodelet.java | 2 +- .../AddTwoIntROS2ServiceClient.java | 1 + .../rosservice/ROS2_ServiceClientTest.java | 34 ++++++++------- .../ROS2_RosTopicPublisherSubscriberTest.java | 41 ++++++++++++++++++- 6 files changed, 62 insertions(+), 20 deletions(-) diff --git a/build.gradle b/build.gradle index 06501eb..f6009e5 100644 --- a/build.gradle +++ b/build.gradle @@ -36,7 +36,7 @@ configurations { } dependencies { - implementation files('../cst-bindings/build/libs/cst-bindings.jar') //RESOLVEU -> estava comentadado + //implementation files('../cst-bindings/build/libs/cst-bindings.jar') //RESOLVEU -> estava comentadado //implementation project(':cst-bindings') // CST Desktop API //api('com.github.CST-Group:cst-desktop:1.1.0') diff --git a/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicPublisherMotorCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicPublisherMotorCodelet.java index 3b5035e..03a466e 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicPublisherMotorCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicPublisherMotorCodelet.java @@ -26,7 +26,7 @@ public abstract class Ros2TopicPublisherMotorCodelet * @param messageType the ROS message class type. Ex: std_msgs.String.class */ public Ros2TopicPublisherMotorCodelet(String id, String topic, Class messageType) { - super(topic, messageType); + super(id,topic, messageType); this.id = topic; } diff --git a/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicSubscriberSensoryCodelet.java b/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicSubscriberSensoryCodelet.java index f95d31a..f542987 100644 --- a/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicSubscriberSensoryCodelet.java +++ b/src/main/java/br/unicamp/meca/system1/codelets/Ros2TopicSubscriberSensoryCodelet.java @@ -25,7 +25,7 @@ public abstract class Ros2TopicSubscriberSensoryCodelet * @param messageType the ROS message class type. Ex: std_msgs.String.class */ public Ros2TopicSubscriberSensoryCodelet(String id, String topic, Class messageType) { - super(topic, messageType); + super(id,topic, messageType); this.id = topic; } diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntROS2ServiceClient.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntROS2ServiceClient.java index c4b0861..eac65fd 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntROS2ServiceClient.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntROS2ServiceClient.java @@ -61,6 +61,7 @@ protected void processServiceResponse(AddTwoIntsResponseMessage response) { if (response != null) { sum = response.sum; tsResp = System.currentTimeMillis(); + System.out.println("Using a: "+a+" b: "+b+" from "+TimeStamp.getStringTimeStamp(tsReq)); System.out.println("RESPONSE Sum=" + sum + " at " + TimeStamp.getStringTimeStamp(tsResp)); } processing = false; diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_ServiceClientTest.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_ServiceClientTest.java index c7ba578..6b215d2 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_ServiceClientTest.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_ServiceClientTest.java @@ -32,6 +32,7 @@ public class ROS2_ServiceClientTest { private static final Logger LOGGER = Logger.getLogger(ROS2_ServiceClientTest.class.getName()); private static MecaMind mecaMind; private volatile Memory motorMemory; + private static AddTwoIntsROS2ServiceProvider serviceProvider; private static void SilenceLoggers() { Logger.getLogger("pinorobotics.rtpstalk").setLevel(Level.OFF); @@ -42,22 +43,25 @@ private static void SilenceLoggers() { public static void setup() { mecaMind = new MecaMind("ROS2_RosServiceClientTest"); Logger.getLogger("id.jros2client").setLevel(Level.OFF); + serviceProvider = new AddTwoIntsROS2ServiceProvider(); + serviceProvider.start(); } @AfterAll public static void cleanup() { - if (mecaMind != null) mecaMind.shutDown(); + //if (mecaMind != null) mecaMind.shutDown(); + serviceProvider.stop(); } @Test public void testROS2_RosServiceCallOnce() throws InterruptedException { System.out.println("\nStarting the RosServiceCallOnce test"); SilenceLoggers(); - setup(); + //setup(); // Start ROS2 service provider - AddTwoIntsROS2ServiceProvider serviceProvider = new AddTwoIntsROS2ServiceProvider(); - serviceProvider.start(); - Thread.sleep(500); // give service time to start +// AddTwoIntsROS2ServiceProvider serviceProvider = new AddTwoIntsROS2ServiceProvider(); +// serviceProvider.start(); +// Thread.sleep(500); // give service time to start // Create memory object for inputs //Memory memory = mecaMind.createMemoryObject("add_two_ints"); @@ -110,9 +114,9 @@ public void testROS2_RosServiceCallOnce() throws InterruptedException { //clientSync.stop(); mecaMind.shutDown(); //Thread.sleep(5000); - clientSync.stop(); - serviceProvider.stop(); - while (serviceProvider.running) Thread.sleep(100); + //clientSync.stop(); + //serviceProvider.stop(); + //while (serviceProvider.running) Thread.sleep(100); System.out.println("The test was finished!"); } @@ -124,11 +128,11 @@ public String cvr(long t) { public void testROS2_RosServiceCallTwice() throws InterruptedException { System.out.println("\nStarting the RosServiceCallTwice test"); SilenceLoggers(); - setup(); + //setup(); // Start ROS2 service provider - AddTwoIntsROS2ServiceProvider serviceProvider = new AddTwoIntsROS2ServiceProvider(); - serviceProvider.start(); - Thread.sleep(500); +// AddTwoIntsROS2ServiceProvider serviceProvider = new AddTwoIntsROS2ServiceProvider(); +// serviceProvider.start(); +// Thread.sleep(500); //Memory memory = mecaMind.createMemoryObject("add_two_ints"); @@ -198,10 +202,10 @@ public void testROS2_RosServiceCallTwice() throws InterruptedException { assertEquals(expectedSum, clientSync.getSum()); mecaMind.shutDown(); - clientSync.stop(); + //clientSync.stop(); //Thread.sleep(5000); - serviceProvider.stop(); - while (serviceProvider.running) Thread.sleep(100); + //serviceProvider.stop(); + //while (serviceProvider.running) Thread.sleep(100); //Thread.sleep(5000); System.out.println("The test was finished!"); } diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_RosTopicPublisherSubscriberTest.java b/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_RosTopicPublisherSubscriberTest.java index ee5cf3d..bca11b3 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_RosTopicPublisherSubscriberTest.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_RosTopicPublisherSubscriberTest.java @@ -49,8 +49,8 @@ public class ROS2_RosTopicPublisherSubscriberTest { public static void setup() { LOGGER.info("Setting up MecaMind for ROS2 Publisher/Subscriber test..."); // optionally silence noisy loggers here if you want: - // Logger.getLogger("pinorobotics.rtpstalk").setLevel(Level.OFF); - // Logger.getLogger("id.jros2client").setLevel(Level.OFF); + Logger.getLogger("pinorobotics.rtpstalk").setLevel(Level.OFF); + Logger.getLogger("id.jros2client").setLevel(Level.OFF); mecaMind = new MecaMind("ROS2_RosTopicPublisherSubscriber"); } @@ -191,6 +191,43 @@ public void testRos2Topics() throws InterruptedException { mecaMind.shutDown(); // Already in @AfterAll } + + @Test + public void testRos2Topics2() throws InterruptedException { + + List motorCodelets = new ArrayList<>(); + ROS2_ChatterTopicPublisher chatterTopicPublisher = new ROS2_ChatterTopicPublisher("chatter"); + motorCodelets.add(chatterTopicPublisher); + + List sensoryCodelets = new ArrayList<>(); + ROS2_ChatterTopicSubscriber chatterTopicSubscriber = new ROS2_ChatterTopicSubscriber("chatter"); + sensoryCodelets.add(chatterTopicSubscriber); + + mecaMind.setIMotorCodelets(motorCodelets); + mecaMind.setISensoryCodelets(sensoryCodelets); + mecaMind.mountMecaMind(); + + mecaMind.start(); + LOGGER.info("MECA Mind started — waiting for topic bridge..."); + + // Give time for nodes to start + Thread.sleep(1000); + + String messageExpected = "Hello World"; + Memory motorMemory = chatterTopicPublisher.getInput(chatterTopicPublisher.getId()); + motorMemory.setI(messageExpected); + + // Wait for the message to propagate + Thread.sleep(2000); + + Memory sensoryMemory = chatterTopicSubscriber.getOutput(chatterTopicSubscriber.getId()); + String messageActual = (String) sensoryMemory.getI(); + + LOGGER.log(Level.INFO, "Expected = \"{0}\", Actual = \"{1}\"", new Object[]{messageExpected, messageActual}); + assertEquals(messageExpected, messageActual); + + mecaMind.shutDown(); // Already in @AfterAll + } } From 7b53743eb03fd0730cd03e69555297650697fd13 Mon Sep 17 00:00:00 2001 From: Jose Renato Borelli Date: Thu, 23 Oct 2025 23:29:29 -0300 Subject: [PATCH 85/89] Fixing MECA tests - no more service stoped error --- build.gradle | 2 +- .../rosservice/ROS2_ServiceClientTest.java | 150 ++++++++++- .../ROS2_RosTopicPublisherSubscriberTest.java | 237 +++++------------- 3 files changed, 209 insertions(+), 180 deletions(-) diff --git a/build.gradle b/build.gradle index f6009e5..003828e 100644 --- a/build.gradle +++ b/build.gradle @@ -36,7 +36,7 @@ configurations { } dependencies { - //implementation files('../cst-bindings/build/libs/cst-bindings.jar') //RESOLVEU -> estava comentadado + implementation files('../cst-bindings/build/libs/cst-bindings-1.1.1.jar') //RESOLVEU -> estava comentadado //implementation project(':cst-bindings') // CST Desktop API //api('com.github.CST-Group:cst-desktop:1.1.0') diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_ServiceClientTest.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_ServiceClientTest.java index 6b215d2..51ef6d4 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_ServiceClientTest.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/ROS2_ServiceClientTest.java @@ -8,10 +8,6 @@ import br.unicamp.meca.mind.MecaMind; import br.unicamp.meca.system1.codelets.IMotorCodelet; -//import br.unicamp.cst.bindings.ros2java; -//import br.unicamp.cst.bindings.ros2java.AddTwoIntsROS2ServiceProvider; - - import java.util.ArrayList; import java.util.List; import java.util.logging.Level; @@ -23,10 +19,12 @@ import org.junit.jupiter.api.Test; /** - * ROS2 migration of the ROS1 RosServiceClientTest + * ROS2 version of the MECA ROS1 RosServiceClientTest * * @author jrborelli */ + + public class ROS2_ServiceClientTest { private static final Logger LOGGER = Logger.getLogger(ROS2_ServiceClientTest.class.getName()); @@ -41,22 +39,156 @@ private static void SilenceLoggers() { @BeforeAll public static void setup() { + SilenceLoggers(); mecaMind = new MecaMind("ROS2_RosServiceClientTest"); - Logger.getLogger("id.jros2client").setLevel(Level.OFF); serviceProvider = new AddTwoIntsROS2ServiceProvider(); serviceProvider.start(); } @AfterAll public static void cleanup() { - //if (mecaMind != null) mecaMind.shutDown(); + if (mecaMind != null) mecaMind.shutDown(); serviceProvider.stop(); } @Test public void testROS2_RosServiceCallOnce() throws InterruptedException { System.out.println("\nStarting the RosServiceCallOnce test"); - SilenceLoggers(); + Thread.sleep(5000); //Necessary, so that the mind can shutdown. + + AddTwoIntROS2ServiceClient clientSync = new AddTwoIntROS2ServiceClient("add_two_ints"); + + List motorCodelets = new ArrayList<>(); + motorCodelets.add(clientSync); + mecaMind.setIMotorCodelets(motorCodelets); + mecaMind.mountMecaMind(); + mecaMind.start(); + + + motorMemory = clientSync.getInput(clientSync.getId()); + + Integer expectedSum = 5; + + Integer[] numsToSum = new Integer[] {2,3}; + motorMemory.setI(numsToSum); + + System.out.println("Nums to sum were changed to {2,3}"); + + long tsstartreq = System.currentTimeMillis(); //clientSync.getTSReq(); + long tsstopreq = tsstartreq; + long tsstartresp = System.currentTimeMillis(); //clientSync.getTSResp(); + long tsstopresp = tsstartresp; + //int id = motorMemory.setI(numsToSum); + // At this point, motorMemory has 1 internal MemoryObject and id should be 0 + //System.out.println("id: "+id); + System.out.println("\n\nNums to sum were changed to {2,3} at "+TimeStamp.getStringTimeStamp(motorMemory.getTimestamp())); + System.out.println("Service situation - req:"+TimeStamp.getStringTimeStamp(tsstartreq)+" resp:"+TimeStamp.getStringTimeStamp(tsstartresp)); + + while (clientSync.getSum()== null || tsstartreq == tsstopreq || tsstartresp == tsstopresp || tsstopresp <= tsstopreq ) { + tsstopresp = clientSync.getTSResp(); + tsstopreq = clientSync.getTSReq(); + clientSync.getSum(); + } + + mecaMind.shutDown(); + + System.out.println("Finished process - req:"+TimeStamp.getStringTimeStamp(tsstopreq)+" resp:"+TimeStamp.getStringTimeStamp(tsstopresp)); + System.out.println("I took "+TimeStamp.getStringTimeStamp(tsstopresp-tsstartreq,"mm:ss.SSS")+ " s to attend the service request !!"); + + assertEquals(expectedSum, clientSync.getSum()); + + System.out.println("The test was finished!"); + } + + public String cvr(long t) { + return TimeStamp.getStringTimeStamp(t,"hh:mm:ss.SSS"); + } + + @Test + public void testROS2_RosServiceCallTwice() throws InterruptedException { + System.out.println("\nStarting the RosServiceCallTwice test"); + + AddTwoIntROS2ServiceClient clientSync = new AddTwoIntROS2ServiceClient("add_two_ints"); + //clientSync.start(); + + List motorCodelets = new ArrayList<>(); + motorCodelets.add(clientSync); + mecaMind.setIMotorCodelets(motorCodelets); + mecaMind.mountMecaMind(); + mecaMind.start(); + + MemoryContainer mc=null; + motorMemory = clientSync.getInput(clientSync.getId()); + + if (motorMemory instanceof MemoryContainer) + mc = (MemoryContainer) motorMemory; + Integer expectedSum = 5; + + // First request + Integer[] numsToSum = new Integer[]{2, 3}; + + long tsstartreq = System.currentTimeMillis(); //clientSync.getTSReq(); + long tsstopreq = tsstartreq; + long tsstartresp = System.currentTimeMillis(); //clientSync.getTSResp(); + long tsstopresp = tsstartresp; + int id = motorMemory.setI(numsToSum); + // At this point, motorMemory has 1 internal MemoryObject and id should be 0 + System.out.println("id: "+id); + System.out.println("\n\nNums to sum were changed to {2,3} at "+TimeStamp.getStringTimeStamp(motorMemory.getTimestamp())); + System.out.println("Service situation - req:"+TimeStamp.getStringTimeStamp(tsstartreq)+" resp:"+TimeStamp.getStringTimeStamp(tsstartresp)); + + while (clientSync.getSum()== null || tsstartreq == tsstopreq || tsstartresp == tsstopresp || tsstopresp <= tsstopreq ) { + tsstopresp = clientSync.getTSResp(); + tsstopreq = clientSync.getTSReq(); + clientSync.getSum(); + System.out.print("."); + } + + System.out.println("\nFinished process - req:"+TimeStamp.getStringTimeStamp(tsstopreq)+" resp:"+TimeStamp.getStringTimeStamp(tsstopresp)); + + System.out.println("I took "+TimeStamp.getStringTimeStamp(tsstopresp-tsstartreq,"mm:ss.SSS")+ " s to attend the service request !!"); + + assertEquals(expectedSum, clientSync.getSum()); + + expectedSum = 6; + + numsToSum = new Integer[] {3,3}; + // This is the tricker part ... instead of calling setI from motorMemory, we should use its MemoryContainer counterpart + mc.setI(numsToSum,0); + System.out.println("\n\nNums to sum were changed to {3,3} at "+TimeStamp.getStringTimeStamp(motorMemory.getTimestamp())); + tsstartreq = clientSync.getTSReq(); + tsstopreq = tsstartreq; + tsstartresp = clientSync.getTSResp(); + tsstopresp = tsstartresp; + System.out.println("Service situation - req:"+TimeStamp.getStringTimeStamp(tsstartreq)+" resp:"+TimeStamp.getStringTimeStamp(tsstartresp)); + + while (clientSync.getSum()== null || tsstartreq == tsstopreq || tsstartresp == tsstopresp || tsstopresp <= tsstopreq ) { + tsstopresp = clientSync.getTSResp(); + tsstopreq = clientSync.getTSReq(); + clientSync.getSum(); + System.out.print("."); + } + + motorMemory.setI(null); + motorMemory = null; + mc.setI(null,0); + mc = null; + mecaMind.shutDown(); + + System.out.println("\nFinished process - req:"+TimeStamp.getStringTimeStamp(tsstopreq)+" resp:"+TimeStamp.getStringTimeStamp(tsstopresp)); + System.out.println("I took "+TimeStamp.getStringTimeStamp(tsstopresp-tsstartreq,"mm:ss.SSS")+ " s to attend the service request !!"); + + assertEquals(expectedSum, clientSync.getSum()); + + System.out.println("The test was finished!"); + } +} + +/* +@Test + public void testROS2_RosServiceCallOnce() throws InterruptedException { + System.out.println("\nStarting the RosServiceCallOnce test"); + //SilenceLoggers(); //setup(); // Start ROS2 service provider // AddTwoIntsROS2ServiceProvider serviceProvider = new AddTwoIntsROS2ServiceProvider(); @@ -209,4 +341,4 @@ public void testROS2_RosServiceCallTwice() throws InterruptedException { //Thread.sleep(5000); System.out.println("The test was finished!"); } -} \ No newline at end of file +*/ \ No newline at end of file diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_RosTopicPublisherSubscriberTest.java b/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_RosTopicPublisherSubscriberTest.java index bca11b3..8eb75c7 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_RosTopicPublisherSubscriberTest.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_RosTopicPublisherSubscriberTest.java @@ -24,34 +24,24 @@ * @author jrborelli */ -import java.time.Duration; -import java.time.Instant; - -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; - - -/** - * Fully asynchronous ROS2 Publisher-Subscriber test using CompletableFuture. - * Reacts immediately when the message arrives. - * - * Author: jrborelli - */ public class ROS2_RosTopicPublisherSubscriberTest { private static final Logger LOGGER = Logger.getLogger(ROS2_RosTopicPublisherSubscriberTest.class.getName()); private static MecaMind mecaMind; + + // optionally silence noisy loggers here if you want: + private static void SilenceLoggers() { + Logger.getLogger("pinorobotics.rtpstalk").setLevel(Level.OFF); + Logger.getLogger("id.jros2client").setLevel(Level.OFF); + } @BeforeAll public static void setup() { + SilenceLoggers(); LOGGER.info("Setting up MecaMind for ROS2 Publisher/Subscriber test..."); - // optionally silence noisy loggers here if you want: - Logger.getLogger("pinorobotics.rtpstalk").setLevel(Level.OFF); - Logger.getLogger("id.jros2client").setLevel(Level.OFF); mecaMind = new MecaMind("ROS2_RosTopicPublisherSubscriber"); + } @AfterAll @@ -63,6 +53,65 @@ public static void teardown() { } @Test + public void testRos2Topics() throws InterruptedException { + + List motorCodelets = new ArrayList<>(); + ROS2_ChatterTopicPublisher chatterTopicPublisher = new ROS2_ChatterTopicPublisher("chatter"); + motorCodelets.add(chatterTopicPublisher); + + List sensoryCodelets = new ArrayList<>(); + ROS2_ChatterTopicSubscriber chatterTopicSubscriber = new ROS2_ChatterTopicSubscriber("chatter"); + sensoryCodelets.add(chatterTopicSubscriber); + + mecaMind.setIMotorCodelets(motorCodelets); + mecaMind.setISensoryCodelets(sensoryCodelets); + mecaMind.mountMecaMind(); + + mecaMind.start(); + LOGGER.info("MECA Mind started — waiting for topic bridge..."); + + // Give time for nodes to start + Thread.sleep(1000); + + String messageExpected = "Hello World"; + Memory motorMemory = chatterTopicPublisher.getInput(chatterTopicPublisher.getId()); + motorMemory.setI(messageExpected); + + final long timeoutMillis = 50000L; + //final long pollIntervalMs = 50L; + final long start = System.currentTimeMillis(); + long timeFinished = 0; + + Memory sensoryMemory = chatterTopicSubscriber.getOutput(chatterTopicSubscriber.getId()); + String messageActual = null; + + while(messageActual==null && (System.currentTimeMillis() - start < timeoutMillis)){ + messageActual = (String) sensoryMemory.getI(); + } + + timeFinished = System.currentTimeMillis() - start; + + LOGGER.log(Level.INFO, "Expected = \"{0}\", Actual = \"{1}\"", new Object[]{messageExpected, messageActual}); + assertEquals(messageExpected, messageActual); + LOGGER.log(Level.INFO, "Message received in {0} seconds", new Object[]{timeFinished}); + + mecaMind.shutDown(); // Already in @AfterAll + } +} + + +/* + +// Add these imports: +import java.time.Duration; +import java.time.Instant; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; + +@Test public void testChatterTopicIntegration() throws Exception { // --- Create specialized codelets --- ROS2_ChatterTopicPublisher publisherCodelet = new ROS2_ChatterTopicPublisher("chatter"); @@ -138,156 +187,4 @@ public void testChatterTopicIntegration() throws Exception { // --- Shutdown --- mecaMind.shutDown(); } - - @Test - public void testRos2Topics() throws InterruptedException { - - List motorCodelets = new ArrayList<>(); - ROS2_ChatterTopicPublisher chatterTopicPublisher = new ROS2_ChatterTopicPublisher("chatter"); - motorCodelets.add(chatterTopicPublisher); - - List sensoryCodelets = new ArrayList<>(); - ROS2_ChatterTopicSubscriber chatterTopicSubscriber = new ROS2_ChatterTopicSubscriber("chatter"); - sensoryCodelets.add(chatterTopicSubscriber); - - LOGGER.log(Level.INFO,"#############" + chatterTopicSubscriber.getId()); - LOGGER.log(Level.INFO,"#############" + chatterTopicPublisher.getId()); - - mecaMind.setIMotorCodelets(motorCodelets); - mecaMind.setISensoryCodelets(sensoryCodelets); - mecaMind.mountMecaMind(); - - mecaMind.start(); - LOGGER.info("MECA Mind started — waiting for topic bridge..."); - - // Give time for nodes to start - Thread.sleep(1000); - - String messageExpected = "Hello World"; - Memory motorMemory = chatterTopicPublisher.getInput(chatterTopicPublisher.getId()); - ////////////////chatterTopicPublisher.getInput(chatterTopicPublisher.getId()).setI(messageExpected); - ////////////////chatterTopicPublisher.getInput(chatterTopicPublisher.getId()).setName("chatter"); - motorMemory.setI(messageExpected); - motorMemory.setName("chatter"); // NOVO - chatterTopicPublisher.addInput(motorMemory);//NOVO - - // Wait for the message to propagate - Thread.sleep(1000); - - //Memory sensoryMemory2 = chatterTopicSubscriber.getOutput(chatterTopicSubscriber.getId()); - //sensoryMemory2.setName("chatter");//NOVO - //chatterTopicSubscriber.addOutput(sensoryMemory2);//NOVO - - Thread.sleep(10000); - - Memory sensoryMemory = chatterTopicSubscriber.getOutput(chatterTopicSubscriber.getId()); - LOGGER.log(Level.INFO,"#############" + chatterTopicSubscriber.getId()); - //chatterTopicSubscriber.getOutput(chatterTopicSubscriber.getId()).setName("chatter"); - ///////////////Memory sensoryMemory = chatterTopicSubscriber.getOutput("chatterTopicSubscriber"); - String messageActual = (String) sensoryMemory.getI(); - - LOGGER.log(Level.INFO, "Expected = \"{0}\", Actual = \"{1}\"", new Object[]{messageExpected, messageActual}); - assertEquals(messageExpected, messageActual); - - mecaMind.shutDown(); // Already in @AfterAll - } - - @Test - public void testRos2Topics2() throws InterruptedException { - - List motorCodelets = new ArrayList<>(); - ROS2_ChatterTopicPublisher chatterTopicPublisher = new ROS2_ChatterTopicPublisher("chatter"); - motorCodelets.add(chatterTopicPublisher); - - List sensoryCodelets = new ArrayList<>(); - ROS2_ChatterTopicSubscriber chatterTopicSubscriber = new ROS2_ChatterTopicSubscriber("chatter"); - sensoryCodelets.add(chatterTopicSubscriber); - - mecaMind.setIMotorCodelets(motorCodelets); - mecaMind.setISensoryCodelets(sensoryCodelets); - mecaMind.mountMecaMind(); - - mecaMind.start(); - LOGGER.info("MECA Mind started — waiting for topic bridge..."); - - // Give time for nodes to start - Thread.sleep(1000); - - String messageExpected = "Hello World"; - Memory motorMemory = chatterTopicPublisher.getInput(chatterTopicPublisher.getId()); - motorMemory.setI(messageExpected); - - // Wait for the message to propagate - Thread.sleep(2000); - - Memory sensoryMemory = chatterTopicSubscriber.getOutput(chatterTopicSubscriber.getId()); - String messageActual = (String) sensoryMemory.getI(); - - LOGGER.log(Level.INFO, "Expected = \"{0}\", Actual = \"{1}\"", new Object[]{messageExpected, messageActual}); - assertEquals(messageExpected, messageActual); - - mecaMind.shutDown(); // Already in @AfterAll - } -} - - -/* -public class ROS2_RosTopicPublisherSubscriberTest { - - private static MecaMind mecaMind; - private static final Logger LOGGER = Logger.getLogger(ROS2_RosTopicPublisherSubscriberTest.class.getName()); - - @BeforeAll - public static void beforeAllTestMethods() { - LOGGER.info("Setting up MecaMind for ROS2 Publisher/Subscriber test..."); - mecaMind = new MecaMind("ROS2_RosTopicPublisherSubscriber"); - } - - @AfterAll - public static void afterAllTestMethods() { - LOGGER.info("Tearing down MecaMind..."); - if (mecaMind != null) { - mecaMind.shutDown(); - } - } - - @Test - public void testRos2Topics() throws InterruptedException { - - List motorCodelets = new ArrayList<>(); - ROS2_ChatterTopicPublisher chatterTopicPublisher = new ROS2_ChatterTopicPublisher("chatter"); - motorCodelets.add(chatterTopicPublisher); - - List sensoryCodelets = new ArrayList<>(); - ROS2_ChatterTopicSubscriber chatterTopicSubscriber = new ROS2_ChatterTopicSubscriber("chatter"); - sensoryCodelets.add(chatterTopicSubscriber); - - mecaMind.setIMotorCodelets(motorCodelets); - mecaMind.setISensoryCodelets(sensoryCodelets); - mecaMind.mountMecaMind(); - - mecaMind.start(); - LOGGER.info("MECA Mind started — waiting for topic bridge..."); - - // Give time for nodes to start - Thread.sleep(1000); - - String messageExpected = "Hello World"; - Memory motorMemory = chatterTopicPublisher.getInput(chatterTopicPublisher.getId()); - motorMemory.setI(messageExpected); - - // Wait for the message to propagate - Thread.sleep(1000); - - Memory sensoryMemory = chatterTopicSubscriber.getOutput(chatterTopicSubscriber.getId()); - String messageActual = (String) sensoryMemory.getI(); - - LOGGER.log(Level.INFO, "Expected = \"{0}\", Actual = \"{1}\"", new Object[]{messageExpected, messageActual}); - assertEquals(messageExpected, messageActual); - - mecaMind.shutDown(); // Already in @AfterAll - } -} - - */ \ No newline at end of file From e3777871faeb4cbbbabc181603a6a7f209e3f6d3 Mon Sep 17 00:00:00 2001 From: rgudwin Date: Thu, 6 Nov 2025 15:16:04 -0300 Subject: [PATCH 86/89] Fixing a non-running test --- README.md | 4 ++-- build.gradle | 10 ++++---- gradle/wrapper/gradle-wrapper.properties | 2 +- .../ROS2_RosTopicPublisherSubscriberTest.java | 24 ++++++++++--------- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 033989f..cad447c 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Note: This library is still under development, and some concepts or features mig ``` dependencies { ... - implementation 'com.github.CST-Group:meca:0.7.0' + implementation 'com.github.CST-Group:meca:0.8.0' } ``` @@ -54,7 +54,7 @@ Sometimes, the version number (tag) in this README gets out of date, as maintain com.github.CST-Group meca - 0.7.0 + 0.8.0 ``` diff --git a/build.gradle b/build.gradle index f6009e5..f1e5a10 100644 --- a/build.gradle +++ b/build.gradle @@ -12,11 +12,11 @@ java { targetCompatibility = JavaVersion.VERSION_17 toolchain { - languageVersion = JavaLanguageVersion.of(21) + languageVersion = JavaLanguageVersion.of(17) } } -version = '0.7.0' +version = '0.8.0' repositories { // Local flat directories for custom jars @@ -39,8 +39,8 @@ dependencies { //implementation files('../cst-bindings/build/libs/cst-bindings.jar') //RESOLVEU -> estava comentadado //implementation project(':cst-bindings') // CST Desktop API - //api('com.github.CST-Group:cst-desktop:1.1.0') - api(':cst-desktop:1.1.1-full') + api('com.github.CST-Group:cst-desktop:1.1.1') + //api(':cst-desktop:1.1.5-full') //CST Bindings (flat JAR) //api name: 'cst-bindings', ext: 'jar' @@ -130,4 +130,4 @@ uberJar { test { useJUnitPlatform() maxParallelForks = 1 -} \ No newline at end of file +} diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index d4081da..bad7c24 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_RosTopicPublisherSubscriberTest.java b/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_RosTopicPublisherSubscriberTest.java index bca11b3..878bb5f 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_RosTopicPublisherSubscriberTest.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rostopic/ROS2_RosTopicPublisherSubscriberTest.java @@ -8,6 +8,7 @@ import br.unicamp.cst.core.entities.Memory; import br.unicamp.cst.core.entities.MemoryObject; +import br.unicamp.cst.support.TimeStamp; import br.unicamp.meca.mind.MecaMind; import br.unicamp.meca.system1.codelets.IMotorCodelet; import br.unicamp.meca.system1.codelets.ISensoryCodelet; @@ -24,13 +25,7 @@ * @author jrborelli */ -import java.time.Duration; -import java.time.Instant; - -import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; /** @@ -215,13 +210,20 @@ public void testRos2Topics2() throws InterruptedException { String messageExpected = "Hello World"; Memory motorMemory = chatterTopicPublisher.getInput(chatterTopicPublisher.getId()); - motorMemory.setI(messageExpected); - - // Wait for the message to propagate - Thread.sleep(2000); - Memory sensoryMemory = chatterTopicSubscriber.getOutput(chatterTopicSubscriber.getId()); + long start = sensoryMemory.getTimestamp(); + motorMemory.setI(messageExpected); + long actual = start; + long now = System.currentTimeMillis(); String messageActual = (String) sensoryMemory.getI(); + while (actual == start && (now-start) < 15000L) { + actual = sensoryMemory.getTimestamp(); + messageActual = (String) sensoryMemory.getI(); + now = System.currentTimeMillis(); + //System.out.println(TimeStamp.getStringTimeStamp(now-start, "HH:mm:ss.SSS")+" "+TimeStamp.getStringTimeStamp(actual-start, "HH:mm:ss.SSS")+" "+messageActual); + Thread.sleep(1000); + } + messageActual = (String) sensoryMemory.getI(); LOGGER.log(Level.INFO, "Expected = \"{0}\", Actual = \"{1}\"", new Object[]{messageExpected, messageActual}); assertEquals(messageExpected, messageActual); From 33c5e95533e2800d95a0f8999aed909c73996f65 Mon Sep 17 00:00:00 2001 From: rgudwin Date: Thu, 6 Nov 2025 16:50:06 -0300 Subject: [PATCH 87/89] Fixing branch compilation to JDK 17 and above --- .github/workflows/java-ci.yml | 2 +- build.gradle | 11 +++-------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/.github/workflows/java-ci.yml b/.github/workflows/java-ci.yml index f813a27..25c4632 100644 --- a/.github/workflows/java-ci.yml +++ b/.github/workflows/java-ci.yml @@ -19,7 +19,7 @@ jobs: id-token: write strategy: matrix: - java: [ '8', '11', '17', '21'] + java: [ '17', '21', '25'] name: JDK ${{ matrix.Java }} build steps: - uses: actions/checkout@v5.0.0 diff --git a/build.gradle b/build.gradle index bbc433f..932bafa 100644 --- a/build.gradle +++ b/build.gradle @@ -36,16 +36,11 @@ configurations { } dependencies { - implementation files('../cst-bindings/build/libs/cst-bindings-1.1.1.jar') //RESOLVEU -> estava comentadado - //implementation project(':cst-bindings') // CST Desktop API - api('com.github.CST-Group:cst-desktop:1.1.1') - //api(':cst-desktop:1.1.5-full') - //CST Bindings (flat JAR) - //api name: 'cst-bindings', ext: 'jar' - + api('com.github.CST-Group:cst-desktop:1.1.1') // This one is for production + //api(':cst-desktop:1.1.5-full') // This one is for new developments only + // JUnit and testing - //testImplementation 'junit:junit:4.12' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.11.0' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.11.0' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' From cf139d07cd11e3327d8ed356359f5d20880e0fd3 Mon Sep 17 00:00:00 2001 From: rgudwin Date: Thu, 6 Nov 2025 16:51:37 -0300 Subject: [PATCH 88/89] Inserting jitpack.xml to force jitpack to compile using JDK 17 --- jitpack.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 jitpack.yml diff --git a/jitpack.yml b/jitpack.yml new file mode 100644 index 0000000..bbaedec --- /dev/null +++ b/jitpack.yml @@ -0,0 +1,3 @@ +jdk: + - openjdk17 + From 5bf620617e7442d8c537e27822f8f8ecb4a0c6c8 Mon Sep 17 00:00:00 2001 From: rgudwin Date: Fri, 14 Nov 2025 10:00:52 -0300 Subject: [PATCH 89/89] Update to use cst-desktop-1.1.2 --- README.md | 4 ++-- build.gradle | 6 +++--- .../rosservice/AddTwoIntROS2ServiceClient.java | 7 +++++-- .../codelets/rosservice/ROS2_ServiceClientTest.java | 12 +++++++++--- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index cad447c..b1b9102 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Note: This library is still under development, and some concepts or features mig ``` dependencies { ... - implementation 'com.github.CST-Group:meca:0.8.0' + implementation 'com.github.CST-Group:meca:0.8.1' } ``` @@ -54,7 +54,7 @@ Sometimes, the version number (tag) in this README gets out of date, as maintain com.github.CST-Group meca - 0.8.0 + 0.8.1 ``` diff --git a/build.gradle b/build.gradle index 932bafa..163d7de 100644 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,7 @@ java { } } -version = '0.8.0' +version = '0.8.1' repositories { // Local flat directories for custom jars @@ -37,8 +37,8 @@ configurations { dependencies { // CST Desktop API - api('com.github.CST-Group:cst-desktop:1.1.1') // This one is for production - //api(':cst-desktop:1.1.5-full') // This one is for new developments only + api('com.github.CST-Group:cst-desktop:1.1.2') // This one is for production + //api(':cst-desktop:1.1.2-full') // This one is for new developments only // JUnit and testing testImplementation 'org.junit.jupiter:junit-jupiter-api:5.11.0' diff --git a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntROS2ServiceClient.java b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntROS2ServiceClient.java index eac65fd..6e588eb 100644 --- a/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntROS2ServiceClient.java +++ b/src/test/java/br/unicamp/meca/system1/codelets/rosservice/AddTwoIntROS2ServiceClient.java @@ -21,8 +21,11 @@ public class AddTwoIntROS2ServiceClient extends Ros2ServiceClientMotorCodelet motorCodelets = new ArrayList<>(); motorCodelets.add(clientSync); mecaMind.setIMotorCodelets(motorCodelets); mecaMind.mountMecaMind(); + List lm = clientSync.getInputs(); + System.out.println("The number of inputs is "+lm.size()); + for (Memory m :lm) { + System.out.println("The name of memory is "+m.getName()); + } mecaMind.start(); @@ -108,8 +115,7 @@ public String cvr(long t) { public void testROS2_RosServiceCallTwice() throws InterruptedException { System.out.println("\nStarting the RosServiceCallTwice test"); - AddTwoIntROS2ServiceClient clientSync = new AddTwoIntROS2ServiceClient("add_two_ints"); - //clientSync.start(); + AddTwoIntROS2ServiceClient clientSync = new AddTwoIntROS2ServiceClient("AddTwoInts","add_two_ints"); List motorCodelets = new ArrayList<>(); motorCodelets.add(clientSync);