From ee8b94514a544dcd48ef9fa086d06b7abc769846 Mon Sep 17 00:00:00 2001
From: rschoene <rene.schoene@tu-dresden.de>
Date: Thu, 21 Apr 2022 17:16:06 +0200
Subject: [PATCH] working on use cases

- changes to protobuf not verified
- many changes are experimental still
---
 .../st/ros3rag/common/SharedMainParts.java    |  4 +--
 .../src/main/proto/cgv_connector.proto        | 20 ++++++++---
 .../src/main/resources/jastadd/types.relast   |  9 +++++
 .../src/main/jastadd/WorldModelB.connect      |  4 +--
 .../src/main/jastadd/WorldModelB.jadd         | 27 +++++++++++----
 .../src/main/jastadd/WorldModelB.relast       | 15 ++++++--
 ros3rag.scaling.a/.gitignore                  |  5 +++
 ros3rag.scaling.a/build.gradle                | 33 ++++++++++++++++++
 .../src/main/jastadd/ScalingModelA.connect    |  1 +
 .../src/main/jastadd/ScalingModelA.jadd       | 18 ++++++++++
 .../src/main/jastadd/ScalingModelA.relast     |  4 +++
 ros3rag.scaling.a/src/main/jastadd/shared     |  1 +
 .../st/scaling/a/ConfigurationScalingA.java   | 24 +++++++++++++
 .../inf/st/scaling/a/MainScalingA.java        | 12 +++++++
 .../src/main/resources/config-scaling-a.yml   |  5 +++
 .../src/main/resources/config-scene-a.json    | 24 +++++++++++++
 .../src/main/resources/log4j2.xml             | 13 +++++++
 ros3rag.scaling.b/.gitignore                  |  5 +++
 ros3rag.scaling.b/build.gradle                | 34 +++++++++++++++++++
 ros3rag.scaling.b/src/main/jastadd/fromPlaceB |  1 +
 .../st/scaling/b/ConfigurationScalingB.java   | 29 ++++++++++++++++
 .../inf/st/scaling/b/MainScalingB.java        | 12 +++++++
 settings.gradle                               |  3 ++
 23 files changed, 286 insertions(+), 17 deletions(-)
 create mode 100644 ros3rag.scaling.a/.gitignore
 create mode 100644 ros3rag.scaling.a/build.gradle
 create mode 100644 ros3rag.scaling.a/src/main/jastadd/ScalingModelA.connect
 create mode 100644 ros3rag.scaling.a/src/main/jastadd/ScalingModelA.jadd
 create mode 100644 ros3rag.scaling.a/src/main/jastadd/ScalingModelA.relast
 create mode 120000 ros3rag.scaling.a/src/main/jastadd/shared
 create mode 100644 ros3rag.scaling.a/src/main/java/de/tudresden/inf/st/scaling/a/ConfigurationScalingA.java
 create mode 100644 ros3rag.scaling.a/src/main/java/de/tudresden/inf/st/scaling/a/MainScalingA.java
 create mode 100644 ros3rag.scaling.a/src/main/resources/config-scaling-a.yml
 create mode 100644 ros3rag.scaling.a/src/main/resources/config-scene-a.json
 create mode 100644 ros3rag.scaling.a/src/main/resources/log4j2.xml
 create mode 100644 ros3rag.scaling.b/.gitignore
 create mode 100644 ros3rag.scaling.b/build.gradle
 create mode 120000 ros3rag.scaling.b/src/main/jastadd/fromPlaceB
 create mode 100644 ros3rag.scaling.b/src/main/java/de/tudresden/inf/st/scaling/b/ConfigurationScalingB.java
 create mode 100644 ros3rag.scaling.b/src/main/java/de/tudresden/inf/st/scaling/b/MainScalingB.java

diff --git a/ros3rag.common/src/main/java/de/tudresden/inf/st/ros3rag/common/SharedMainParts.java b/ros3rag.common/src/main/java/de/tudresden/inf/st/ros3rag/common/SharedMainParts.java
index b1127e1..2f443ae 100644
--- a/ros3rag.common/src/main/java/de/tudresden/inf/st/ros3rag/common/SharedMainParts.java
+++ b/ros3rag.common/src/main/java/de/tudresden/inf/st/ros3rag/common/SharedMainParts.java
@@ -54,7 +54,7 @@ public abstract class SharedMainParts<MqttHandler extends SharedMainParts.MqttHa
 
   private Map<String, String> channelDescriptions() {
     return new LinkedHashMap<>() {{
-      put(TOPIC_MODEL, "Print current model (detailed if message starts with 'detail");
+      put(TOPIC_MODEL, "Print current model (detailed if message starts with 'detail')");
       put(TOPIC_REWIND, "Rewind app to start");
       put(TOPIC_EXIT, "Exit app");
     }};
@@ -186,7 +186,7 @@ public abstract class SharedMainParts<MqttHandler extends SharedMainParts.MqttHa
   private void logStatus(String message) {
     logger.info(message);
     String content = getModelInfos(model, message.equals("Start") || message.startsWith("detail"));
-    logger.info("WorldModelB\n{}", content);
+    logger.info("WorldModel\n{}", content);
     if (mainHandler != null) {
       mainHandler.publish(TOPIC_STATUS, content.getBytes(StandardCharsets.UTF_8));
     }
diff --git a/ros3rag.common/src/main/proto/cgv_connector.proto b/ros3rag.common/src/main/proto/cgv_connector.proto
index ca2f8c4..1488917 100644
--- a/ros3rag.common/src/main/proto/cgv_connector.proto
+++ b/ros3rag.common/src/main/proto/cgv_connector.proto
@@ -54,6 +54,7 @@ message Scene {
 }
 
 // the selection is done by the CGV framework and sent to ROS
+// FIXME can be removed
 message Selection {
     string id = 1; // the id corresponds to an id of an Object in a Scene
 }
@@ -61,11 +62,22 @@ message Selection {
 // vvv from rs vvv.
 // Merged message to contain both pick and place in one
 message MergedSelection {
-    string idRobot = 1; // the id corresponds to and id of the robot Object that should execute this operation
-    string idPick = 2; // the id corresponds to an id of the Object in a Scene to be picked
-    string idPlace = 3; // the id corresponds to an id of the Object in a Scene where the picked object shall be placed
+    string idRobot = 1;  // id of the robot that should execute this operation
+    string idPick = 2;  // id of the object in the scene to be picked
+    string idPlace = 3;  // id of the location the picked object shall be placed. TODO should be a position
 }
+
+message ConfigChange {
+    string idCollaborationZone = 1;  // id of collaboration zone to change
+    string idRobotNewOwner = 2;  // id of robot that will become new owner
+}
+
+message Evacuate {
+    string idRobot = 1;  // id of robot that need to move out of its currently defined collision objects
+}
+
 // Reachability of objects, as reported by MoveIt
+// FIXME can be removed
 message Reachability {
     message ObjectReachability {
         string idObject = 1; // the id of the object to reach
@@ -73,4 +85,4 @@ message Reachability {
     }
     string idRobot = 1; // the id of the robot arm
     repeated ObjectReachability objects = 2; // all objects reachable
-}
\ No newline at end of file
+}
diff --git a/ros3rag.common/src/main/resources/jastadd/types.relast b/ros3rag.common/src/main/resources/jastadd/types.relast
index c99b527..8e2c8ba 100644
--- a/ros3rag.common/src/main/resources/jastadd/types.relast
+++ b/ros3rag.common/src/main/resources/jastadd/types.relast
@@ -19,3 +19,12 @@ LogicalDropOffLocation : LogicalObjectOfInterest ;
 LogicalMovableObject : LogicalObjectOfInterest ;
 rel LogicalDropOffLocation.ContainedObject* <-> LogicalMovableObject.LocatedAt? ;
 // rs: assumption movable object can only be at one location at the same time, i.e., no overlapping locations
+
+// new as of 2022-04-21
+LocationMapping ::= LocationMappingPair* ;
+LocationMappingPair ;
+rel LocationMappingPair.Location -> LogicalDropOffLocation ;
+rel LocationMappingPair.Position* -> Position ;  // TODO what is the target here? is it really Position?
+
+// should this be only in site-B??
+CollaborationZone : LogicalDropOffLocation ;
diff --git a/ros3rag.placeB/src/main/jastadd/WorldModelB.connect b/ros3rag.placeB/src/main/jastadd/WorldModelB.connect
index 9e3097a..7949de6 100644
--- a/ros3rag.placeB/src/main/jastadd/WorldModelB.connect
+++ b/ros3rag.placeB/src/main/jastadd/WorldModelB.connect
@@ -8,9 +8,9 @@ receive Robot.CanReachObjectOfInterestWrapper using ParseReachability, ConvertRe
 send WorldModelB.NextOperation using PrintOperation ;
 
 PrintOperation maps Operation op to byte[] {:
-  var result = op.toMergedSelection();
+  byte[] result = op.toProtobufByteArray();
   if (result == null) {
     reject();
   }
-  return result.toByteArray();
+  return result;
 :}
diff --git a/ros3rag.placeB/src/main/jastadd/WorldModelB.jadd b/ros3rag.placeB/src/main/jastadd/WorldModelB.jadd
index 518e868..e88ebe7 100644
--- a/ros3rag.placeB/src/main/jastadd/WorldModelB.jadd
+++ b/ros3rag.placeB/src/main/jastadd/WorldModelB.jadd
@@ -203,23 +203,30 @@ aspect Computation {
 //}
 
 aspect AttributeMappings {
-  //--- toMergedSelection ---
-  syn de.tudresden.inf.st.ceti.MergedSelection Operation.toMergedSelection();
-  eq ErrorOperation.toMergedSelection() {
+  //--- toProtobufByteArray ---
+  syn byte[] Operation.toProtobufByteArray() = null;
+  eq ErrorOperation.toProtobufByteArray() {
     System.err.println(getErrorMessage());
     return null;
   }
-  eq Pick.toMergedSelection() {
+  eq Pick.toProtobufByteArray() {
     throw new RuntimeException("Separate Pick operation not supported yet!");
   }
-  eq Place.toMergedSelection() {
+  eq Place.toProtobufByteArray() {
     throw new RuntimeException("Separate Place operation not supported yet!");
   }
-  eq PickAndPlace.toMergedSelection() = de.tudresden.inf.st.ceti.MergedSelection.newBuilder()
+  eq PickAndPlace.toProtobufByteArray() = de.tudresden.inf.st.ceti.MergedSelection.newBuilder()
         .setIdRobot(getRobotToExecute().getName())
         .setIdPick(getObjectToPick().getName())
         .setIdPlace(getTargetLocation().getName())
-        .build();
+        .build().toByteArray();
+  eq ConfigChange.toProtobufByteArray() = de.tudresden.inf.st.ceti.ConfigChange.newBuilder()
+        .setIdRobotNewOwner(getRobotToExecute().getName())
+        .setIdCollaborationZone(getCollaborationZone().getName())
+        .build().toByteArray();
+  eq Evacuate.toProtobufByteArray() = de.tudresden.inf.st.ceti.Evacuate.newBuilder()
+        .setIdRobot(getRobotToExecute().getName())
+        .build().toByteArray();
 }
 
 aspect Navigation {
@@ -263,6 +270,12 @@ aspect Printing {
   eq ErrorOperation.prettyPrint() {
     return "+Error: " + getErrorMessage() + "+";
   }
+  eq ConfigChange.prettyPrint() {
+    return "+ConfigChange: " + getRobotToExecute().prettyPrint() + " owns " + getCollaborationZone().prettyPrint() + "+";
+  }
+  eq Evacuate.prettyPrint() {
+    return "+Evacuate: " + getRobotToExecute().prettyPrint() + "+";
+  }
 }
 
 aspect Resolving {
diff --git a/ros3rag.placeB/src/main/jastadd/WorldModelB.relast b/ros3rag.placeB/src/main/jastadd/WorldModelB.relast
index 8925831..2d26f86 100644
--- a/ros3rag.placeB/src/main/jastadd/WorldModelB.relast
+++ b/ros3rag.placeB/src/main/jastadd/WorldModelB.relast
@@ -1,6 +1,8 @@
 WorldModelB ::= Robot* [MyScene:Scene] OtherScene:LogicalScene* /NextOperation:Operation/ TestingOtherScene:LogicalScene* ;
 
-Robot ::= <Name:String> CanReachObjectOfInterestWrapper ;
+Robot ::= <Name:String> CanReachObjectOfInterestWrapper <Busy:boolean> ;
+rel Robot.OwnedCollaborationZone* <-> CollaborationZone.Owner? ;
+rel Robot.OccupiedCollaborationZone? <-> CollaborationZone.Occupient? ;
 
 abstract Difference ;
 rel Difference.Object -> LogicalMovableObject ;
@@ -14,10 +16,19 @@ rel DifferenceObjectMisplaced.PreviousLocation -> LogicalDropOffLocation ;
 abstract Operation ;
 rel Operation.RobotToExecute? -> Robot ;
 ErrorOperation : Operation ::= <ErrorMessage:String> ;
+
 Pick : Operation ;
-Place : Operation ;
 rel Pick.ObjectToPick -> LogicalMovableObject ;
+
+Place : Operation ;
 rel Place.TargetLocation -> LogicalDropOffLocation ;
+
 PickAndPlace : Operation ;
 rel PickAndPlace.ObjectToPick -> LogicalMovableObject ;
 rel PickAndPlace.TargetLocation -> LogicalDropOffLocation ;
+
+ConfigChange : Operation ;
+rel ConfigChange.CollaborationZone -> LogicalDropOffLocation ;
+// TODO should be: rel ConfigChange.CollaborationZone -> CollaborationZone ;
+
+Evacuate : Operation ;
diff --git a/ros3rag.scaling.a/.gitignore b/ros3rag.scaling.a/.gitignore
new file mode 100644
index 0000000..87b4cdd
--- /dev/null
+++ b/ros3rag.scaling.a/.gitignore
@@ -0,0 +1,5 @@
+build
+src/gen-res/
+src/gen/
+out/
+*.class
diff --git a/ros3rag.scaling.a/build.gradle b/ros3rag.scaling.a/build.gradle
new file mode 100644
index 0000000..b858870
--- /dev/null
+++ b/ros3rag.scaling.a/build.gradle
@@ -0,0 +1,33 @@
+buildscript {
+    repositories.mavenCentral()
+    dependencies {
+        classpath group: 'org.jastadd', name: 'jastaddgradle', version: "${jastadd_gradle_version}"
+    }
+}
+
+plugins {
+    id 'ros3rag.java-application-conventions'
+    id 'ros3rag.java-ragconnect-conventions'
+}
+
+mainClassName = 'de.tudresden.inf.st.scaling.a.MainScalingA'
+
+task simpleRun(type: JavaExec) {
+    group 'application'
+    classpath sourceSets.main.runtimeClasspath
+    main = "de.tudresden.inf.st.placeA.SimpleMainA"
+
+}
+
+dependencies {
+    implementation project(':ros3rag.common')
+}
+
+ext.sharedJastAddDir = 'src/main/jastadd/shared'
+ext.ragConnectInputGrammar = 'src/main/jastadd/ScalingModelA.relast'
+ext.ragConnectInputConnect = 'src/main/jastadd/ScalingModelA.connect'
+ext.ragConnectRootNode = 'CompleteWorld'
+ext.relastFiles = ["src/gen/jastadd/ScalingModelA.relast", "src/gen/jastadd/RagConnect.relast"]
+ext.jastaddAstPackage = 'de.tudresden.inf.st.scaling.a.ast'
+
+apply from: '../ros3rag.common/src/main/resources/tasks.gradle'
diff --git a/ros3rag.scaling.a/src/main/jastadd/ScalingModelA.connect b/ros3rag.scaling.a/src/main/jastadd/ScalingModelA.connect
new file mode 100644
index 0000000..5908eeb
--- /dev/null
+++ b/ros3rag.scaling.a/src/main/jastadd/ScalingModelA.connect
@@ -0,0 +1 @@
+send indexed CompleteWorld.View ;
diff --git a/ros3rag.scaling.a/src/main/jastadd/ScalingModelA.jadd b/ros3rag.scaling.a/src/main/jastadd/ScalingModelA.jadd
new file mode 100644
index 0000000..35fd74c
--- /dev/null
+++ b/ros3rag.scaling.a/src/main/jastadd/ScalingModelA.jadd
@@ -0,0 +1,18 @@
+aspect Computation {
+  syn JastAddList<LogicalScene> CompleteWorld.getViewList() {
+    JastAddList<LogicalScene> result = new JastAddList<>();
+    for (int i = 0, length = getNumberOfViews(); i < length; i++) {
+      LogicalScene view = new LogicalScene();
+
+      result.addChild(view);
+    }
+    return result;
+  }
+}
+
+aspect RagConnectFixes {
+  // FIXME (in ragconnect) when sending list NTAs, the reset method is wrong.
+  private void CompleteWorld.getView_reset() {
+    getViewList_reset();
+  }
+}
diff --git a/ros3rag.scaling.a/src/main/jastadd/ScalingModelA.relast b/ros3rag.scaling.a/src/main/jastadd/ScalingModelA.relast
new file mode 100644
index 0000000..939c122
--- /dev/null
+++ b/ros3rag.scaling.a/src/main/jastadd/ScalingModelA.relast
@@ -0,0 +1,4 @@
+//CompleteWorld ::= <NumberOfViews:int> <DistributionStrategy> /View:WorldModelA*/ ;
+//WorldModelA ::= [Scene] /LogicalScene/ ;
+
+CompleteWorld ::= LogicalScene <NumberOfViews:int> <DistributionStrategy> /View:LogicalScene*/ ;
diff --git a/ros3rag.scaling.a/src/main/jastadd/shared b/ros3rag.scaling.a/src/main/jastadd/shared
new file mode 120000
index 0000000..6a2416e
--- /dev/null
+++ b/ros3rag.scaling.a/src/main/jastadd/shared
@@ -0,0 +1 @@
+../../../../ros3rag.common/src/main/resources/jastadd
\ No newline at end of file
diff --git a/ros3rag.scaling.a/src/main/java/de/tudresden/inf/st/scaling/a/ConfigurationScalingA.java b/ros3rag.scaling.a/src/main/java/de/tudresden/inf/st/scaling/a/ConfigurationScalingA.java
new file mode 100644
index 0000000..6d27c44
--- /dev/null
+++ b/ros3rag.scaling.a/src/main/java/de/tudresden/inf/st/scaling/a/ConfigurationScalingA.java
@@ -0,0 +1,24 @@
+package de.tudresden.inf.st.scaling.a;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import java.util.List;
+
+/**
+ * New Data class for initial configuration.
+ *
+ * @author rschoene - Initial contribution
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ConfigurationScalingA {
+  public String mqttHost;
+  public String filenameInitialScene;
+  public String coordinatorMqttTopicPrefix;
+
+  public int numberOfViews;
+  public String distributionStrategy;
+
+  public boolean useCoordinator() {
+    return coordinatorMqttTopicPrefix != null;
+  }
+}
diff --git a/ros3rag.scaling.a/src/main/java/de/tudresden/inf/st/scaling/a/MainScalingA.java b/ros3rag.scaling.a/src/main/java/de/tudresden/inf/st/scaling/a/MainScalingA.java
new file mode 100644
index 0000000..3959d84
--- /dev/null
+++ b/ros3rag.scaling.a/src/main/java/de/tudresden/inf/st/scaling/a/MainScalingA.java
@@ -0,0 +1,12 @@
+package de.tudresden.inf.st.scaling.a;
+
+/**
+ * TODO: Add description.
+ *
+ * @author rschoene - Initial contribution
+ */
+public class MainScalingA {
+  public static void main(String[] args) {
+    System.out.println("Hi A");
+  }
+}
diff --git a/ros3rag.scaling.a/src/main/resources/config-scaling-a.yml b/ros3rag.scaling.a/src/main/resources/config-scaling-a.yml
new file mode 100644
index 0000000..6d1ddfb
--- /dev/null
+++ b/ros3rag.scaling.a/src/main/resources/config-scaling-a.yml
@@ -0,0 +1,5 @@
+mqttHost: "localhost"
+filenameInitialScene: "src/main/resources/config-scene-a.json"
+coordinatorMqttTopicPrefix: "coordinating/rag-a"
+numberOfViews: 5
+distributionStrategy: "random"
diff --git a/ros3rag.scaling.a/src/main/resources/config-scene-a.json b/ros3rag.scaling.a/src/main/resources/config-scene-a.json
new file mode 100644
index 0000000..92b9ce4
--- /dev/null
+++ b/ros3rag.scaling.a/src/main/resources/config-scene-a.json
@@ -0,0 +1,24 @@
+{ "objects": [
+  { "id": "tablePillar1","pos": { "x": 0.77,"y": 0.77,"z": 0.325 },"size": { "length": 0.06,"width": 0.06,"height": 0.65 },"orientation": { "w": 1 },"color": { "r": 255,"g": 222,"b": 173 } },
+  { "id": "tablePillar2","pos": { "x": -0.77,"y": -0.77,"z": 0.325 },"size": { "length": 0.06,"width": 0.06,"height": 0.65 },"orientation": { "w": 1 },"color": { "r": 255,"g": 222,"b": 173 } },
+  { "id": "tablePillar3","pos": { "x": -0.77,"y": 0.77,"z": 0.325 },"size": { "length": 0.06,"width": 0.06,"height": 0.65 },"orientation": { "w": 1 },"color": { "r": 255,"g": 222,"b": 173 } },
+  { "id": "tablePillar4","pos": { "x": 0.77,"y": -0.77,"z": 0.325 },"size": { "length": 0.06,"width": 0.06,"height": 0.65 },"orientation": { "w": 1 },"color": { "r": 255,"g": 222,"b": 173 } },
+  { "id": "table","pos": { "z": 0.7 },"size": { "length": 1.6,"width": 1.6,"height": 0.1 },"orientation": { "w": 1 },"color": { "r": 255,"g": 222,"b": 173 } },
+  { "id": "binBlue","type": "DROP_OFF_LOCATION","pos": { "x": -0.34,"y": 0.49,"z": 0.8325 },"size": { "length": 0.21,"width": 0.3,"height": 0.165 },"orientation": { "w": 1 },"color": { "b": 1 } },
+  { "id": "binRed","type": "DROP_OFF_LOCATION","pos": { "x": 0.06,"y": 0.49,"z": 0.8325 },"size": { "length": 0.21,"width": 0.3,"height": 0.165 },"orientation": { "w": 1 },"color": { "r": 1 } },
+  { "id": "binGreen","type": "DROP_OFF_LOCATION","pos": { "x": 0.46,"y": 0.49,"z": 0.8325 },"size": { "length": 0.21,"width": 0.3,"height": 0.165 },"orientation": { "w": 1 },"color": { "g": 1 } },
+  { "id": "binYellow","type": "DROP_OFF_LOCATION","pos": { "x": 1.46,"y": 0.49,"z": 0.8325 },"size": { "length": 0.21,"width": 0.3,"height": 0.165 },"orientation": { "w": 1 },"color": { "r": 1, "g": 1 } },
+  { "id": "binPurple","type": "DROP_OFF_LOCATION","pos": { "x": 2.46,"y": 0.49,"z": 0.8325 },"size": { "length": 0.21,"width": 0.3,"height": 0.165 },"orientation": { "w": 1 },"color": { "r": 1, "b": 1 } },
+  { "id": "objectRed1","type": "BOX","pos": { "x": 0.5,"y": -0.1,"z": 0.8105 },"size": { "length": 0.031,"width": 0.062,"height": 0.121 },"orientation": { "z": 0.382683,"w": 0.92388 },"color": { "r": 1 } },
+  { "id": "objectRed2","type": "BOX","pos": { "x": 0.25,"y": -0.2,"z": 0.8105 },"size": { "length": 0.031,"width": 0.062,"height": 0.121 },"orientation": { "w": 1 },"color": { "r": 1 } },
+  { "id": "objectRed3","type": "BOX","pos": { "x": -0.4,"z": 0.819 },"size": { "length": 0.031,"width": 0.031,"height": 0.138 },"orientation": { "z": 0.382683,"w": 0.92388 },"color": { "r": 1 } },
+  { "id": "objectGreen1","type": "BOX","pos": { "x": 0.45,"y": -0.3,"z": 0.8105 },"size": {"length":0.031,"width":0.062,"height":0.121},"orientation": { "z": 0.382683,"w": 0.92388 },"color": { "g": 1 } },
+  { "id": "objectGreen2","type": "BOX","pos": { "x": -0.45,"y": -0.2,"z": 0.8105 },"size": {"length":0.031,"width":0.031,"height":0.138},"orientation": { "z": 0.382683,"w": 0.92388 },"color": { "g": 1 } },
+  { "id": "objectGreen3","type": "BOX","pos": { "x": 0.1,"y": -0.3,"z": 0.819 },"size": {"length":0.031,"width":0.062,"height":0.121},"orientation": { "z": 0.382683,"w": 0.92388 },"color": { "g": 1 } },
+  { "id": "objectBlue1","type": "BOX","pos": { "x": 0.25,"y": -0.4,"z": 0.8105 },"size": { "length": 0.031,"width": 0.062,"height": 0.121 },"orientation": { "z": 0.382683,"w": 0.92388 },"color": { "b": 1 } },
+  { "id": "objectBlue2","type": "BOX","pos": { "x": -0.3,"y": -0.3,"z": 0.8105 },"size": { "length": 0.031,"width": 0.062,"height": 0.121 },"orientation": { "z": 0.382683,"w": 0.92388 },"color": { "b": 1 } },
+  { "id": "objectBlue3","type": "BOX","pos": { "x": 0.4,"z": 0.819 },"size": { "length": 0.031,"width": 0.031,"height": 0.138 },"orientation": { "z": 0.382683,"w": 0.92388 },"color": { "b": 1 } },
+  { "id": "objectYellow1","type": "BOX","pos": { "x": 0.4,"z": 0.819 },"size": { "length": 0.031,"width": 0.031,"height": 0.138 },"orientation": { "z": 0.382683,"w": 0.92388 },"color": { "r": 1, "g": 1 } },
+  { "id": "objectPurple1","type": "BOX","pos": { "x": 0.3,"z": 0.819 },"size": { "length": 0.031,"width": 0.031,"height": 0.138 },"orientation": { "z": 0.382683,"w": 0.92388 },"color": { "r": 1, "b": 1 } },
+  { "id": "arm","type": "ARM","pos": { "z": 0.75 },"size": { },"orientation": { "w": 1 },"color": { "r": 1.00,"g": 1.00,"b": 1.00 } }
+] }
diff --git a/ros3rag.scaling.a/src/main/resources/log4j2.xml b/ros3rag.scaling.a/src/main/resources/log4j2.xml
new file mode 100644
index 0000000..98d9c02
--- /dev/null
+++ b/ros3rag.scaling.a/src/main/resources/log4j2.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="INFO">
+    <Appenders>
+        <Console name="Console" target="SYSTEM_OUT">
+            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{1.} - %msg%n"/>
+        </Console>
+    </Appenders>
+    <Loggers>
+        <Root level="debug">
+            <AppenderRef ref="Console"/>
+        </Root>
+    </Loggers>
+</Configuration>
diff --git a/ros3rag.scaling.b/.gitignore b/ros3rag.scaling.b/.gitignore
new file mode 100644
index 0000000..87b4cdd
--- /dev/null
+++ b/ros3rag.scaling.b/.gitignore
@@ -0,0 +1,5 @@
+build
+src/gen-res/
+src/gen/
+out/
+*.class
diff --git a/ros3rag.scaling.b/build.gradle b/ros3rag.scaling.b/build.gradle
new file mode 100644
index 0000000..27c72a4
--- /dev/null
+++ b/ros3rag.scaling.b/build.gradle
@@ -0,0 +1,34 @@
+buildscript {
+    repositories.mavenLocal()
+    repositories.mavenCentral()
+    dependencies {
+        classpath group: 'org.jastadd', name: 'jastaddgradle', version: "${jastadd_gradle_version}"
+    }
+}
+
+plugins {
+    id 'ros3rag.java-application-conventions'
+    id 'ros3rag.java-ragconnect-conventions'
+}
+
+mainClassName = 'de.tudresden.inf.st.scaling.b.MainScalingB'
+
+task simpleRun(type: JavaExec) {
+    group 'application'
+    classpath sourceSets.main.runtimeClasspath
+    main = "de.tudresden.inf.st.placeB.SimpleMainB"
+}
+
+dependencies {
+    implementation project(':ros3rag.common')
+    testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-params', version: "${jupiter_version}"
+}
+
+ext.sharedJastAddDir = 'src/main/jastadd/fromPlaceB/shared'
+ext.ragConnectInputGrammar = 'src/main/jastadd/fromPlaceB/WorldModelB.relast'
+ext.ragConnectInputConnect = 'src/main/jastadd/fromPlaceB/WorldModelB.connect'
+ext.ragConnectRootNode = 'WorldModelB'
+ext.relastFiles = ["src/gen/jastadd/WorldModelB.relast", "src/main/jastadd/fromPlaceB/BFS/BFS.relast", "src/main/jastadd/fromPlaceB/RobotReachabilityToBFS.relast", "src/gen/jastadd/RagConnect.relast"]
+ext.jastaddAstPackage = 'de.tudresden.inf.st.scaling.b.ast'
+
+apply from: '../ros3rag.common/src/main/resources/tasks.gradle'
diff --git a/ros3rag.scaling.b/src/main/jastadd/fromPlaceB b/ros3rag.scaling.b/src/main/jastadd/fromPlaceB
new file mode 120000
index 0000000..1a094a0
--- /dev/null
+++ b/ros3rag.scaling.b/src/main/jastadd/fromPlaceB
@@ -0,0 +1 @@
+../../../../ros3rag.placeB/src/main/jastadd
\ No newline at end of file
diff --git a/ros3rag.scaling.b/src/main/java/de/tudresden/inf/st/scaling/b/ConfigurationScalingB.java b/ros3rag.scaling.b/src/main/java/de/tudresden/inf/st/scaling/b/ConfigurationScalingB.java
new file mode 100644
index 0000000..bdbd643
--- /dev/null
+++ b/ros3rag.scaling.b/src/main/java/de/tudresden/inf/st/scaling/b/ConfigurationScalingB.java
@@ -0,0 +1,29 @@
+package de.tudresden.inf.st.scaling.b;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import java.util.List;
+
+/**
+ * New Data class for initial configuration.
+ *
+ * @author rschoene - Initial contribution
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ConfigurationScalingB {
+  public String mqttHost;
+  public String filenameInitialScene;
+  public boolean useReachability;
+  public String coordinatorMqttTopicPrefix;
+  public List<ReachabilityConfig> reachability;
+  public int numberOfRobots;
+
+  public static class ReachabilityConfig {
+    public String idRobot;
+    public String filename;
+  }
+
+  public boolean useCoordinator() {
+    return coordinatorMqttTopicPrefix != null;
+  }
+}
diff --git a/ros3rag.scaling.b/src/main/java/de/tudresden/inf/st/scaling/b/MainScalingB.java b/ros3rag.scaling.b/src/main/java/de/tudresden/inf/st/scaling/b/MainScalingB.java
new file mode 100644
index 0000000..c9c8f8c
--- /dev/null
+++ b/ros3rag.scaling.b/src/main/java/de/tudresden/inf/st/scaling/b/MainScalingB.java
@@ -0,0 +1,12 @@
+package de.tudresden.inf.st.scaling.b;
+
+/**
+ * TODO: Add description.
+ *
+ * @author rschoene - Initial contribution
+ */
+public class MainScalingB {
+  public static void main(String[] args) {
+    System.out.println("Hi B");
+  }
+}
diff --git a/settings.gradle b/settings.gradle
index 19ff0e6..7f2471d 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -9,3 +9,6 @@ rootProject.name = 'ros3rag'
 include 'ros3rag.placeA'
 include 'ros3rag.placeB'
 include 'ros3rag.common'
+
+include 'ros3rag.scaling.a'
+include 'ros3rag.scaling.b'
-- 
GitLab