Skip to content
Snippets Groups Projects
Commit 18d88605 authored by René Schöne's avatar René Schöne
Browse files

working on real collaboration

- update config file structure
- add new configs
- (temporarily) ignore height for isLocatedAt
- ignore unresolved locations when computing operations
- handle unresolved robots
parent 97baeda6
Branches
Tags
No related merge requests found
Pipeline #13544 passed
Showing
with 1732 additions and 149 deletions
...@@ -12,14 +12,12 @@ import java.util.List; ...@@ -12,14 +12,12 @@ import java.util.List;
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public class Configuration { public class Configuration {
public String mqttHost; public String mqttHost;
public String filenameInitialScene; public String filenameInitialSceneA;
public String filenameRegions; public String filenameRegions;
public boolean useReachability;
public String coordinatorMqttTopicPrefix; public String coordinatorMqttTopicPrefix;
public List<ReachabilityConfig> reachability; public List<ReachabilityConfig> reachability;
public static class ReachabilityConfig { public static class ReachabilityConfig {
public String idRobot;
public String filename; public String filename;
} }
......
package de.tudresden.inf.st.ros3rag.common; package de.tudresden.inf.st.ros3rag.common;
import de.tudresden.inf.st.ceti.Scene;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
...@@ -26,7 +25,6 @@ public abstract class SharedMainParts<MqttHandler extends SharedMainParts.MqttHa ...@@ -26,7 +25,6 @@ public abstract class SharedMainParts<MqttHandler extends SharedMainParts.MqttHa
private final String TOPIC_STATUS; private final String TOPIC_STATUS;
private final String TOPIC_REWIND; private final String TOPIC_REWIND;
private final String TOPIC_EXIT; private final String TOPIC_EXIT;
private final String TOPIC_SCENE_INIT;
private static final String TOPIC_SUFFIX_COORDINATOR_STATUS = "status"; private static final String TOPIC_SUFFIX_COORDINATOR_STATUS = "status";
private static final String TOPIC_SUFFIX_COORDINATOR_COMMAND = "command"; private static final String TOPIC_SUFFIX_COORDINATOR_COMMAND = "command";
...@@ -46,12 +44,8 @@ public abstract class SharedMainParts<MqttHandler extends SharedMainParts.MqttHa ...@@ -46,12 +44,8 @@ public abstract class SharedMainParts<MqttHandler extends SharedMainParts.MqttHa
this.TOPIC_STATUS = cellName + "/status"; this.TOPIC_STATUS = cellName + "/status";
this.TOPIC_REWIND = cellName + "/rewind"; this.TOPIC_REWIND = cellName + "/rewind";
this.TOPIC_EXIT = cellName + "/exit"; this.TOPIC_EXIT = cellName + "/exit";
this.TOPIC_SCENE_INIT = cellName + "/scene/init";
} }
protected abstract MqttHandler createMqttHandler();
private Map<String, String> channelDescriptions() { private Map<String, String> channelDescriptions() {
return new LinkedHashMap<>() {{ 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')");
...@@ -137,8 +131,6 @@ public abstract class SharedMainParts<MqttHandler extends SharedMainParts.MqttHa ...@@ -137,8 +131,6 @@ public abstract class SharedMainParts<MqttHandler extends SharedMainParts.MqttHa
} }
} }
protected abstract void createSpecificMainHandlerConnections();
private void rewind(String statusMessage) throws Exception { private void rewind(String statusMessage) throws Exception {
if (model != null) { if (model != null) {
logger.debug("Closing previous connections for {}", cellName); logger.debug("Closing previous connections for {}", cellName);
...@@ -147,8 +139,8 @@ public abstract class SharedMainParts<MqttHandler extends SharedMainParts.MqttHa ...@@ -147,8 +139,8 @@ public abstract class SharedMainParts<MqttHandler extends SharedMainParts.MqttHa
logger.debug("Creating world model for {}", cellName); logger.debug("Creating world model for {}", cellName);
model = createWorldModel(); model = createWorldModel();
logger.debug("Reading scene for {}", cellName); logger.debug("Reading robots for {}", cellName);
Scene scene = readSceneAndRobots(); readRobotsAndReachability();
logger.debug("Setup model connection for {}", cellName); logger.debug("Setup model connection for {}", cellName);
model.ragconnectCheckIncremental(); model.ragconnectCheckIncremental();
...@@ -167,7 +159,6 @@ public abstract class SharedMainParts<MqttHandler extends SharedMainParts.MqttHa ...@@ -167,7 +159,6 @@ public abstract class SharedMainParts<MqttHandler extends SharedMainParts.MqttHa
logStatus(statusMessage); logStatus(statusMessage);
mainHandler.publish(TOPIC_SCENE_INIT, scene.toByteArray());
if (config.useCoordinator()) { if (config.useCoordinator()) {
logger.debug("Publishing ready for {}", cellName); logger.debug("Publishing ready for {}", cellName);
mainHandler.publish(joinTopics(config.coordinatorMqttTopicPrefix, TOPIC_SUFFIX_COORDINATOR_STATUS), mainHandler.publish(joinTopics(config.coordinatorMqttTopicPrefix, TOPIC_SUFFIX_COORDINATOR_STATUS),
...@@ -175,11 +166,15 @@ public abstract class SharedMainParts<MqttHandler extends SharedMainParts.MqttHa ...@@ -175,11 +166,15 @@ public abstract class SharedMainParts<MqttHandler extends SharedMainParts.MqttHa
} }
} }
protected abstract Scene readSceneAndRobots() throws Exception; protected abstract MqttHandler createMqttHandler();
protected abstract void connectEndpoints() throws IOException; protected abstract void createSpecificMainHandlerConnections();
protected abstract WorldModel createWorldModel() throws Exception;
protected abstract WorldModel createWorldModel(); protected abstract void readRobotsAndReachability() throws Exception;
protected abstract void connectEndpoints() throws IOException;
protected abstract String getModelInfos(WorldModel model, boolean detailed); protected abstract String getModelInfos(WorldModel model, boolean detailed);
......
...@@ -40,7 +40,8 @@ aspect Resolving { ...@@ -40,7 +40,8 @@ aspect Resolving {
syn DropOffLocation LogicalMovableObject.myLocation() { syn DropOffLocation LogicalMovableObject.myLocation() {
// classical reference attribute (was relation, but not allowed with RagConnect) // classical reference attribute (was relation, but not allowed with RagConnect)
return containingScene().resolveObjectOfInterest(getNameOfMyLocation()).asDropOffLocation(); ObjectOfInterest obj = containingScene().resolveObjectOfInterest(getNameOfMyLocation());
return obj == null ? null : obj.asDropOffLocation();
} }
} }
...@@ -66,7 +67,7 @@ aspect Computation { ...@@ -66,7 +67,7 @@ aspect Computation {
// we use half of the size of to the position as it is in the center of the location // we use half of the size of to the position as it is in the center of the location
double halfLocationLength = 0.5 * locationSize.getLength(); double halfLocationLength = 0.5 * locationSize.getLength();
double halfLocationWidth = 0.5 * locationSize.getWidth(); double halfLocationWidth = 0.5 * locationSize.getWidth();
double halfLocationHeight = 0.5 * locationSize.getHeight(); // double halfLocationHeight = 0.5 * locationSize.getHeight();
double rotatedX = rotatedObjectVector.getX(); double rotatedX = rotatedObjectVector.getX();
double rotatedY = rotatedObjectVector.getY(); double rotatedY = rotatedObjectVector.getY();
...@@ -80,8 +81,8 @@ aspect Computation { ...@@ -80,8 +81,8 @@ aspect Computation {
// halfLocationHeight); // halfLocationHeight);
return LT(-halfLocationLength, rotatedX) && LT(rotatedX, halfLocationLength) && return LT(-halfLocationLength, rotatedX) && LT(rotatedX, halfLocationLength) &&
LT(-halfLocationWidth, rotatedY) && LT(rotatedY, halfLocationWidth) && LT(-halfLocationWidth, rotatedY) && LT(rotatedY, halfLocationWidth); // &&
LT(-halfLocationHeight, rotatedZ) && LT(rotatedZ, halfLocationHeight); //LT(-halfLocationHeight, rotatedZ) && LT(rotatedZ, halfLocationHeight);
} }
syn MovableObject DropOffLocation.getObjectLocatedHere() { syn MovableObject DropOffLocation.getObjectLocatedHere() {
......
...@@ -38,6 +38,11 @@ public class MainA extends SharedMainParts<MqttHandler, WorldModelA> { ...@@ -38,6 +38,11 @@ public class MainA extends SharedMainParts<MqttHandler, WorldModelA> {
new MainA(configFile).run(); new MainA(configFile).run();
} }
@Override
protected MqttHandler createMqttHandler() {
return new MqttHandler("mainHandlerA");
}
@Override @Override
protected void createSpecificMainHandlerConnections() { protected void createSpecificMainHandlerConnections() {
mainHandler.newConnection(TOPIC_DEMO_MOVE_objectRed1_BLUE, bytes -> mainHandler.newConnection(TOPIC_DEMO_MOVE_objectRed1_BLUE, bytes ->
...@@ -55,17 +60,17 @@ public class MainA extends SharedMainParts<MqttHandler, WorldModelA> { ...@@ -55,17 +60,17 @@ public class MainA extends SharedMainParts<MqttHandler, WorldModelA> {
} }
@Override @Override
protected de.tudresden.inf.st.ceti.Scene readSceneAndRobots() throws Exception { protected WorldModelA createWorldModel() throws Exception {
/// Reading scene
de.tudresden.inf.st.ceti.Scene scene = readScene( de.tudresden.inf.st.ceti.Scene scene = readScene(
UtilA.pathToDirectoryOfPlaceA().resolve(config.filenameInitialScene) UtilA.pathToDirectoryOfPlaceA().resolve(config.filenameInitialSceneA)
); );
Scene myScene = UtilA.convert(scene); Scene myScene = UtilA.convert(scene);
model.setScene(myScene); return new WorldModelA().setScene(myScene);
}
@Override
protected void readRobotsAndReachability() {
// no robots to be set // no robots to be set
return scene;
} }
@Override @Override
...@@ -74,16 +79,6 @@ public class MainA extends SharedMainParts<MqttHandler, WorldModelA> { ...@@ -74,16 +79,6 @@ public class MainA extends SharedMainParts<MqttHandler, WorldModelA> {
model.connectLogicalScene(mqttUri(TOPIC_SCENE_UPDATE_TO_PLACE_B, config), true); model.connectLogicalScene(mqttUri(TOPIC_SCENE_UPDATE_TO_PLACE_B, config), true);
} }
@Override
protected MqttHandler createMqttHandler() {
return new MqttHandler("mainHandlerA");
}
@Override
protected WorldModelA createWorldModel() {
return new WorldModelA();
}
@Override @Override
protected String getModelInfos(WorldModelA worldModelA, boolean detailed) { protected String getModelInfos(WorldModelA worldModelA, boolean detailed) {
return UtilA.getModelInfos(model, detailed); return UtilA.getModelInfos(model, detailed);
......
mqttHost: "localhost" mqttHost: "localhost"
filenameInitialScene: "src/main/resources/config-scene-a.json" filenameInitialSceneA: "src/main/resources/config-scene-a.json"
useReachability: false
coordinatorMqttTopicPrefix: "coordinating/rag-a" coordinatorMqttTopicPrefix: "coordinating/rag-a"
config-scene-a-placeworld.json
\ No newline at end of file
{ "objects": [
{ "id": "target","type": "DROP_OFF_LOCATION","pos": { "x": 8,"y": 3,"z": 0.8325 },"size": { "length": 0.21,"width": 0.3,"height": 0.165 },"orientation": { "w": 1 },"color": { "r": 1 } },
{ "id": "bigBlue","type": "BOX","pos": { "x": 8,"y": 3,"z": 0.8105 },"size": { "length": 0.031,"width": 0.062,"height": 0.121 },"orientation": { "z": 0.382683,"w": 0.92388 },"color": { "r": 1 } }
] }
regions-a-placeworld.json
\ No newline at end of file
{
"regions": [
{ "name": "G", "positions": ["target"] }
]
}
...@@ -24,6 +24,7 @@ aspect RobotReachabilityToBFS { ...@@ -24,6 +24,7 @@ aspect RobotReachabilityToBFS {
continue; continue;
} }
List<DropOffLocation> reachableLocations = robot.reachableObjects().stream() List<DropOffLocation> reachableLocations = robot.reachableObjects().stream()
.filter(Objects::nonNull)
.filter(ObjectOfInterest::isDropOffLocation) .filter(ObjectOfInterest::isDropOffLocation)
.map(ObjectOfInterest::asDropOffLocation) .map(ObjectOfInterest::asDropOffLocation)
.collect(java.util.stream.Collectors.toList()); .collect(java.util.stream.Collectors.toList());
......
...@@ -350,7 +350,10 @@ aspect Navigation { ...@@ -350,7 +350,10 @@ aspect Navigation {
return result; return result;
} }
syn boolean Robot.isBusy() = worldModelB().getMyScene().resolveObjectOfInterest(getName()).asRobotObject().getActive(); syn boolean Robot.isBusy() {
ObjectOfInterest obj = worldModelB().getMyScene().resolveObjectOfInterest(getName());
return obj == null ? false : obj.asRobotObject().getActive();
}
} }
aspect GlueForShared { aspect GlueForShared {
......
...@@ -4,14 +4,12 @@ import de.tudresden.inf.st.ceti.Reachability; ...@@ -4,14 +4,12 @@ import de.tudresden.inf.st.ceti.Reachability;
import de.tudresden.inf.st.placeB.ast.*; import de.tudresden.inf.st.placeB.ast.*;
import de.tudresden.inf.st.ros3rag.common.Configuration; import de.tudresden.inf.st.ros3rag.common.Configuration;
import de.tudresden.inf.st.ros3rag.common.SharedMainParts; import de.tudresden.inf.st.ros3rag.common.SharedMainParts;
import de.tudresden.inf.st.ros3rag.common.Util;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import static de.tudresden.inf.st.ros3rag.common.Util.mqttUri; import static de.tudresden.inf.st.ros3rag.common.Util.mqttUri;
import static de.tudresden.inf.st.ros3rag.common.Util.readScene;
/** /**
* Entry point for RAG model in place B. * Entry point for RAG model in place B.
...@@ -19,7 +17,6 @@ import static de.tudresden.inf.st.ros3rag.common.Util.readScene; ...@@ -19,7 +17,6 @@ import static de.tudresden.inf.st.ros3rag.common.Util.readScene;
* @author rschoene - Initial contribution * @author rschoene - Initial contribution
*/ */
public class MainB extends SharedMainParts<MqttHandler, WorldModelB> { public class MainB extends SharedMainParts<MqttHandler, WorldModelB> {
private final String TOPIC_ROBOT_REACHABILITY;
private final String TOPIC_MY_SCENE_UPDATE_FROM_ROS; private final String TOPIC_MY_SCENE_UPDATE_FROM_ROS;
private final String TOPIC_COMMAND; private final String TOPIC_COMMAND;
private final String TOPIC_OTHER_SCENE_UPDATE_FROM_PLACE_A; private final String TOPIC_OTHER_SCENE_UPDATE_FROM_PLACE_A;
...@@ -27,7 +24,6 @@ public class MainB extends SharedMainParts<MqttHandler, WorldModelB> { ...@@ -27,7 +24,6 @@ public class MainB extends SharedMainParts<MqttHandler, WorldModelB> {
MainB(String configFile) { MainB(String configFile) {
super("place-b", UtilB.pathToDirectoryOfPlaceB().resolve(configFile)); super("place-b", UtilB.pathToDirectoryOfPlaceB().resolve(configFile));
this.TOPIC_ROBOT_REACHABILITY = cellName + "/reachability/%s";
this.TOPIC_MY_SCENE_UPDATE_FROM_ROS = cellName + "/scene/update"; this.TOPIC_MY_SCENE_UPDATE_FROM_ROS = cellName + "/scene/update";
this.TOPIC_COMMAND = cellName + "/command"; this.TOPIC_COMMAND = cellName + "/command";
...@@ -41,6 +37,11 @@ public class MainB extends SharedMainParts<MqttHandler, WorldModelB> { ...@@ -41,6 +37,11 @@ public class MainB extends SharedMainParts<MqttHandler, WorldModelB> {
new MainB(configFile).run(); new MainB(configFile).run();
} }
@Override
protected MqttHandler createMqttHandler() {
return new MqttHandler("mainHandlerB");
}
@Override @Override
protected void createSpecificMainHandlerConnections() { protected void createSpecificMainHandlerConnections() {
mainHandler.newConnection(TOPIC_DEMO_MOVE_objectRed1_RED, bytes -> mainHandler.newConnection(TOPIC_DEMO_MOVE_objectRed1_RED, bytes ->
...@@ -49,53 +50,39 @@ public class MainB extends SharedMainParts<MqttHandler, WorldModelB> { ...@@ -49,53 +50,39 @@ public class MainB extends SharedMainParts<MqttHandler, WorldModelB> {
} }
@Override @Override
protected de.tudresden.inf.st.ceti.Scene readSceneAndRobots() throws Exception { protected WorldModelB createWorldModel() {
/// Reading scene and robots WorldModelB result = new WorldModelB();
de.tudresden.inf.st.ceti.Scene scene = readScene( result.addOtherScene(new LogicalScene());
UtilB.pathToDirectoryOfPlaceB().resolve(config.filenameInitialScene) return result;
);
Scene myScene = UtilB.convert(scene);
model.setMyScene(myScene);
for (String name : Util.extractRobotNames(scene)) {
Robot robot = UtilB.createRobot(name);
model.addRobot(robot);
// assumption: robots do not change during runtime, so we have stable connections
robot.connectCanReachObjectOfInterestWrapper(mqttUri(String.format(TOPIC_ROBOT_REACHABILITY, name), config));
} }
/// Set (dummy) reachability, if configured @Override
if (config.useReachability) { protected void readRobotsAndReachability() throws Exception {
model.setMyScene(new Scene());
// init robots and reachability
for (Configuration.ReachabilityConfig reachabilityConfig : config.reachability) { for (Configuration.ReachabilityConfig reachabilityConfig : config.reachability) {
Robot robot = model.findRobot(reachabilityConfig.idRobot).orElseThrow( // assumption: robots do not change during runtime, so we have stable connections
() -> new IllegalArgumentException("Could not find robot with name " + reachabilityConfig.idRobot)
);
Path path = UtilB.pathToDirectoryOfPlaceB().resolve(Paths.get(reachabilityConfig.filename)); Path path = UtilB.pathToDirectoryOfPlaceB().resolve(Paths.get(reachabilityConfig.filename));
Reachability reachability = UtilB.readReachability(path); Reachability reachability = UtilB.readReachability(path);
Robot robot = UtilB.createRobot(reachability.getIdRobot());
model.addRobot(robot);
CanReachObjectOfInterestWrapper reachabilityWrapper = UtilB.convert(reachability); CanReachObjectOfInterestWrapper reachabilityWrapper = UtilB.convert(reachability);
robot.setCanReachObjectOfInterestWrapper(reachabilityWrapper); robot.setCanReachObjectOfInterestWrapper(reachabilityWrapper);
} }
} }
return scene;
}
@Override @Override
protected void connectEndpoints() throws IOException { protected void connectEndpoints() throws IOException {
model.connectMyScene(mqttUri(TOPIC_MY_SCENE_UPDATE_FROM_ROS, config)); model.connectMyScene(mqttUri(TOPIC_MY_SCENE_UPDATE_FROM_ROS, config));
model.connectOtherScene(mqttUri(TOPIC_OTHER_SCENE_UPDATE_FROM_PLACE_A, config), 0); model.connectOtherScene(mqttUri(TOPIC_OTHER_SCENE_UPDATE_FROM_PLACE_A, config), 0);
model.connectNextOperation(mqttUri(TOPIC_COMMAND, config), false); model.connectNextOperation(mqttUri(TOPIC_COMMAND, config), false);
for (Robot robot : model.getRobotList()) {
// self-loop
robot.connectOwnedCollaborationZoneNames(mqttUri(TOPIC_COMMAND, config));
} }
@Override
protected MqttHandler createMqttHandler() {
return new MqttHandler("mainHandlerB");
}
@Override
protected WorldModelB createWorldModel() {
WorldModelB result = new WorldModelB();
result.addOtherScene(new LogicalScene());
return result;
} }
@Override @Override
......
...@@ -28,8 +28,43 @@ import java.util.stream.Collectors; ...@@ -28,8 +28,43 @@ import java.util.stream.Collectors;
*/ */
public class SimpleMainB { public class SimpleMainB {
private static final Logger logger = LogManager.getLogger(SimpleMainB.class); private static final Logger logger = LogManager.getLogger(SimpleMainB.class);
boolean exitAutomatically = true;
boolean useMini = true; static class Scenario {
final String suffix;
final boolean loadAndChangeScenes;
final boolean exitAutomatically;
final String mqttHost;
final String topicSceneUpdateB;
final String topicCommand;
Scenario(String suffix) {
this(suffix, true, true,
"localhost", "place-b/scene/update", "place-b/command");
}
Scenario(String suffix, boolean loadAndChangeScenes, boolean exitAutomatically,
String mqttHost, String topicSceneUpdateB, String topicCommand) {
this.suffix = suffix;
this.loadAndChangeScenes = loadAndChangeScenes;
this.exitAutomatically = exitAutomatically;
this.mqttHost = mqttHost;
this.topicSceneUpdateB = topicSceneUpdateB;
this.topicCommand = topicCommand;
}
}
Scenario s2022 = new Scenario("2022");
Scenario sMini = new Scenario("mini");
Scenario sPlaceworld = new Scenario("placeworld", false, false,
"192.168.0.122",
"/ceti_cell_placeworld/scene/update",
"/ceti_cell_placeworld/command");
Scenario sPlaceworldManual = new Scenario("placeworld-manual", false, false,
"localhost",
"/ceti_cell_placeworld/scene/update",
"/ceti_cell_placeworld/command");
@SuppressWarnings("unused" )
Scenario[] allScenarios = new Scenario[] { s2022, sMini, sPlaceworld, sPlaceworldManual };
final Scenario scenario = sPlaceworldManual;
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
System.out.println("Running SimpleMainB"); System.out.println("Running SimpleMainB");
...@@ -42,31 +77,29 @@ public class SimpleMainB { ...@@ -42,31 +77,29 @@ public class SimpleMainB {
} }
private void readModelAndReceiveFromA() throws Exception { private void readModelAndReceiveFromA() throws Exception {
final String suffix = useMini ? "mini" : "2022";
Configuration config = new Configuration(); Configuration config = new Configuration();
config.mqttHost = "localhost"; config.mqttHost = scenario.mqttHost;
config.filenameInitialScene = "src/main/resources/config-scene-b-" + suffix + ".json"; String filenameInitialSceneB = "src/main/resources/config-scene-b-" + scenario.suffix + ".json";
config.filenameRegions = "src/main/resources/regions-b-" + suffix + ".json"; config.filenameRegions = "src/main/resources/regions-b-" + scenario.suffix + ".json";
ReachabilityConfig reachabilityR1 = new ReachabilityConfig(); ReachabilityConfig reachabilityR1 = new ReachabilityConfig();
reachabilityR1.idRobot = "R1"; reachabilityR1.filename = "src/main/resources/reachability-b-r1-" + scenario.suffix + ".json";
reachabilityR1.filename = "src/main/resources/reachability-b-r1-" + suffix + ".json";
ReachabilityConfig reachabilityR2 = new ReachabilityConfig(); ReachabilityConfig reachabilityR2 = new ReachabilityConfig();
reachabilityR2.idRobot = "R2"; reachabilityR2.filename = "src/main/resources/reachability-b-r2-" + scenario.suffix + ".json";
reachabilityR2.filename = "src/main/resources/reachability-b-r2-" + suffix + ".json";
config.reachability = Arrays.asList(reachabilityR1, reachabilityR2); config.reachability = Arrays.asList(reachabilityR1, reachabilityR2);
Configuration configA = new Configuration(); Configuration configA = new Configuration();
configA.filenameInitialScene = "src/main/resources/config-scene-a-" + suffix + ".json"; String filenameInitialSceneA = "src/main/resources/config-scene-a-" + scenario.suffix + ".json";
configA.filenameRegions = "src/main/resources/regions-a-" + suffix + ".json"; configA.filenameRegions = "src/main/resources/regions-a-" + scenario.suffix + ".json";
final String topicSceneUpdateB = "place-b/scene/update"; final String topicSceneUpdateB = scenario.topicSceneUpdateB;
final String topicUpdateFromPlaceA = "update/logical/fromA"; final String topicUpdateFromPlaceA = "update/logical/fromA";
final String topicCommand = "place-b/command"; final String topicCommand = scenario.topicCommand;
final String topicExit = "place-b/exit"; final String topicExit = "place-b/exit";
final String topicModel = "place-b/model"; final String topicModel = "place-b/model";
final String topicModelStatus = "place-b/status"; final String topicModelStatus = "place-b/status";
logger.info("Using scenario {}", scenario.suffix);
WorldModelB model = new WorldModelB(); WorldModelB model = new WorldModelB();
model.addOtherScene(new LogicalScene()); model.addOtherScene(new LogicalScene());
...@@ -75,30 +108,36 @@ public class SimpleMainB { ...@@ -75,30 +108,36 @@ public class SimpleMainB {
mqttHandler.waitUntilReady(2, TimeUnit.SECONDS); mqttHandler.waitUntilReady(2, TimeUnit.SECONDS);
model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS); model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS);
Scene myScene;
// read initial scene // read initial scene
Path initialSceneFile = UtilB.pathToDirectoryOfPlaceB().resolve(config.filenameInitialScene); Path initialSceneFile = UtilB.pathToDirectoryOfPlaceB().resolve(filenameInitialSceneB);
de.tudresden.inf.st.ceti.Scene scene = Util.readScene(initialSceneFile); de.tudresden.inf.st.ceti.Scene initialScene = Util.readScene(initialSceneFile);
Scene myScene = UtilB.convert(scene); if (scenario.loadAndChangeScenes) {
myScene = UtilB.convert(initialScene);
} else {
myScene = new Scene();
mqttHandler.newConnection("coordinating/rag-b/command", bytes -> {
if (new String(bytes).equals("start")) {
mqttHandler.publish(scenario.topicSceneUpdateB, initialScene.toByteArray());
}
});
}
model.setMyScene(myScene); model.setMyScene(myScene);
// read and set regions // read and set regions
File regionBFile = UtilB.pathToDirectoryOfPlaceB().resolve(config.filenameRegions).toFile(); File regionBFile = UtilB.pathToDirectoryOfPlaceB().resolve(config.filenameRegions).toFile();
UtilB.setRegions(model, Util.parseRegionConfig(regionBFile)); UtilB.setRegions(model, Util.parseRegionConfig(regionBFile));
// init robots (copied from MainB) // init robots and reachability
for (String name : Util.extractRobotNames(scene)) {
Robot robot = UtilB.createRobot(name);
model.addRobot(robot);
// assumption: robots do not change during runtime, so we have stable connections
}
// init reachability (copied from MainB)
for (ReachabilityConfig reachabilityConfig : config.reachability) { for (ReachabilityConfig reachabilityConfig : config.reachability) {
Robot robot = model.findRobot(reachabilityConfig.idRobot).orElseThrow( // assumption: robots do not change during runtime, so we have stable connections
() -> new IllegalArgumentException("Could not find robot with id " + reachabilityConfig.idRobot)
);
Path path = UtilB.pathToDirectoryOfPlaceB().resolve(Paths.get(reachabilityConfig.filename)); Path path = UtilB.pathToDirectoryOfPlaceB().resolve(Paths.get(reachabilityConfig.filename));
Reachability reachability = UtilB.readReachability(path); Reachability reachability = UtilB.readReachability(path);
Robot robot = UtilB.createRobot(reachability.getIdRobot());
model.addRobot(robot);
CanReachObjectOfInterestWrapper reachabilityWrapper = UtilB.convert(reachability); CanReachObjectOfInterestWrapper reachabilityWrapper = UtilB.convert(reachability);
robot.setCanReachObjectOfInterestWrapper(reachabilityWrapper); robot.setCanReachObjectOfInterestWrapper(reachabilityWrapper);
} }
...@@ -138,7 +177,7 @@ public class SimpleMainB { ...@@ -138,7 +177,7 @@ public class SimpleMainB {
}); });
// read scene from A, serialize it and send it via mqtt // read scene from A, serialize it and send it via mqtt
Path sceneAFile = Util.pathToModuleDirectory("ros3rag.placeA").resolve(configA.filenameInitialScene); Path sceneAFile = Util.pathToModuleDirectory("ros3rag.placeA").resolve(filenameInitialSceneA);
File regionAFile = Util.pathToModuleDirectory("ros3rag.placeA").resolve(configA.filenameRegions).toFile(); File regionAFile = Util.pathToModuleDirectory("ros3rag.placeA").resolve(configA.filenameRegions).toFile();
de.tudresden.inf.st.ceti.Scene scenePlaceA = Util.readScene(sceneAFile); de.tudresden.inf.st.ceti.Scene scenePlaceA = Util.readScene(sceneAFile);
Scene sceneFromPlaceA = UtilB.convert(scenePlaceA); Scene sceneFromPlaceA = UtilB.convert(scenePlaceA);
...@@ -149,6 +188,7 @@ public class SimpleMainB { ...@@ -149,6 +188,7 @@ public class SimpleMainB {
LogicalScene logicalSceneFromPlaceA = sceneFromPlaceA.getLogicalScene(); LogicalScene logicalSceneFromPlaceA = sceneFromPlaceA.getLogicalScene();
byte[] bytesToSend = _ragconnect__apply__TreeDefaultLogicalSceneToBytesMapping(logicalSceneFromPlaceA); byte[] bytesToSend = _ragconnect__apply__TreeDefaultLogicalSceneToBytesMapping(logicalSceneFromPlaceA);
if (scenario.loadAndChangeScenes) {
describedWait(1, "send new logical scene" ); describedWait(1, "send new logical scene" );
mqttHandler.publish(topicUpdateFromPlaceA, bytesToSend); mqttHandler.publish(topicUpdateFromPlaceA, bytesToSend);
...@@ -157,7 +197,7 @@ public class SimpleMainB { ...@@ -157,7 +197,7 @@ public class SimpleMainB {
// set object O1 to position of P-E in sceneB and publish it // set object O1 to position of P-E in sceneB and publish it
describedWait(3, "send updated sceneB (P-E)"); describedWait(3, "send updated sceneB (P-E)");
scene = updatePositionOfObject(scene, "O1", myScene.resolveObjectOfInterest("P-E").getPosition()); de.tudresden.inf.st.ceti.Scene scene = updatePositionOfObject(initialScene, "O1", myScene.resolveObjectOfInterest("P-E").getPosition());
mqttHandler.publish(topicSceneUpdateB, scene.toByteArray()); mqttHandler.publish(topicSceneUpdateB, scene.toByteArray());
describedWait(4, "set R1 to not busy"); describedWait(4, "set R1 to not busy");
...@@ -180,8 +220,15 @@ public class SimpleMainB { ...@@ -180,8 +220,15 @@ public class SimpleMainB {
describedWait(9, "print model status"); describedWait(9, "print model status");
mqttHandler.publish(topicModel, "detailed".getBytes(StandardCharsets.UTF_8)); mqttHandler.publish(topicModel, "detailed".getBytes(StandardCharsets.UTF_8));
} else {
mqttHandler.newConnection("coordinating/rag-a/command", bytes -> {
if (new String(bytes).equals("start")) {
mqttHandler.publish(topicUpdateFromPlaceA, bytesToSend);
}
});
}
if (exitAutomatically) { if (scenario.exitAutomatically) {
TimeUnit.SECONDS.sleep(5); TimeUnit.SECONDS.sleep(5);
exitCondition.countDown(); exitCondition.countDown();
} }
...@@ -197,7 +244,7 @@ public class SimpleMainB { ...@@ -197,7 +244,7 @@ public class SimpleMainB {
static de.tudresden.inf.st.ceti.Scene updatePositionOfObject( static de.tudresden.inf.st.ceti.Scene updatePositionOfObject(
de.tudresden.inf.st.ceti.Scene scene, de.tudresden.inf.st.ceti.Scene scene,
String objectName, @SuppressWarnings("SameParameterValue" ) String objectName,
Position newPosition) { Position newPosition) {
return updateObject(scene, objectName, obj -> { return updateObject(scene, objectName, obj -> {
Object.Builder builder = obj.toBuilder(); Object.Builder builder = obj.toBuilder();
...@@ -218,8 +265,7 @@ public class SimpleMainB { ...@@ -218,8 +265,7 @@ public class SimpleMainB {
static de.tudresden.inf.st.ceti.Scene updateObject( static de.tudresden.inf.st.ceti.Scene updateObject(
de.tudresden.inf.st.ceti.Scene scene, de.tudresden.inf.st.ceti.Scene scene,
String objectName, String objectName,
Function<Object, Object> change Function<Object, Object> change) {
) {
List<Object> objectsList = scene.getObjectsList(); List<Object> objectsList = scene.getObjectsList();
Object newObj = null; Object newObj = null;
int index, objectsListSize; int index, objectsListSize;
......
mqttHost: "localhost"
useReachability: true
reachability:
- filename: "src/main/resources/reachability-b-arm1-placeworld.json"
- filename: "src/main/resources/reachability-b-arm2-placeworld.json"
coordinatorMqttTopicPrefix: "coordinating/rag-b"
mqttHost: "localhost" mqttHost: "localhost"
filenameInitialScene: "src/main/resources/config-scene-b.json"
useReachability: true
reachability: reachability:
- idRobot: "arm1" - filename: "src/main/resources/dummy-reachability-b-arm1.json"
filename: "src/main/resources/dummy-reachability-b-arm1.json" - filename: "src/main/resources/dummy-reachability-b-arm2.json"
- idRobot: "arm2" - filename: "src/main/resources/dummy-reachability-b-arm3.json"
filename: "src/main/resources/dummy-reachability-b-arm2.json"
- idRobot: "arm3"
filename: "src/main/resources/dummy-reachability-b-arm3.json"
coordinatorMqttTopicPrefix: "coordinating/rag-b" coordinatorMqttTopicPrefix: "coordinating/rag-b"
This diff is collapsed.
reachability-b-arm1-placeworld.json
\ No newline at end of file
{
"idRobot": "arm1",
"objects": [
{ "idObject": "A1", "reachable": true },
{ "idObject": "B1", "reachable": true },
{ "idObject": "B2", "reachable": true },
{ "idObject": "C1", "reachable": true },
{ "idObject": "cz1", "reachable": true },
{ "idObject": "G1", "reachable": false }
]
}
reachability-b-arm2-placeworld.json
\ No newline at end of file
{
"idRobot": "arm2",
"objects": [
{ "idObject": "A1", "reachable": false },
{ "idObject": "B1", "reachable": false },
{ "idObject": "B2", "reachable": false },
{ "idObject": "C1", "reachable": false },
{ "idObject": "cz1", "reachable": true },
{ "idObject": "G1", "reachable": true }
]
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment