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

update

- generalize demo commands
- avoid sending duplicate commands for same robot
- direct manipulation in mappings is dangerous (tested, added only for documentation)
- use NTAs for error operations
parent cd5729b8
Branches
No related tags found
No related merge requests found
...@@ -15,6 +15,5 @@ dependencies { ...@@ -15,6 +15,5 @@ dependencies {
relast group: 'org.jastadd', name: 'relast', version: "0.4.0-143" relast group: 'org.jastadd', name: 'relast', version: "0.4.0-143"
ragconnect group: 'de.tudresden.inf.st', name: 'ragconnect', version: '1.0.0-alpha-203' ragconnect group: 'de.tudresden.inf.st', name: 'ragconnect', version: '1.0.0-alpha-203'
implementation group: 'de.tudresden.inf.st', name: 'dumpAst', version: '1.0.2-68' implementation group: 'de.tudresden.inf.st', name: 'dumpAst', version: '1.0.3-69'
} }
...@@ -46,7 +46,9 @@ ConvertCommand maps de.tudresden.inf.st.ceti.Command command to Operation {: ...@@ -46,7 +46,9 @@ ConvertCommand maps de.tudresden.inf.st.ceti.Command command to Operation {:
// --- sending --- // --- sending ---
send WorldModelB.NextOperation using PrintOperation ; send WorldModelB.NextOperation using PrintOperation ;
// (direct manipulation is dangerous) send WorldModelB.NextOperation using PrintAndRememberOperation ;
send Robot.myPosition(String) ; send Robot.myPosition(String) ;
// (direct manipulation is dangerous) send Robot.myPosition(String) using ImmediateUpdate ;
PrintOperation maps Operation op to byte[] {: PrintOperation maps Operation op to byte[] {:
byte[] result = op.toProtobufByteArray(); byte[] result = op.toProtobufByteArray();
...@@ -56,6 +58,23 @@ PrintOperation maps Operation op to byte[] {: ...@@ -56,6 +58,23 @@ PrintOperation maps Operation op to byte[] {:
return result; return result;
:} :}
// (direct manipulation is dangerous)
//PrintAndRememberOperation maps Operation op to byte[] {:
// byte[] result = op.toProtobufByteArray();
// if (result == null) {
// reject();
// }
// ((WorldModelB) this).addExecutedOperation(op);
// return result;
//:}
//
// (direct manipulation is dangerous)
//ImmediateUpdate maps String pos to String {:
// Robot robot = (Robot) this;
// robot.setCurrentPosition(pos);
// return pos;
//:}
ConfigChangeCommandCheckForOwnedCollaborationZone maps byte[] bytes to String {: ConfigChangeCommandCheckForOwnedCollaborationZone maps byte[] bytes to String {:
de.tudresden.inf.st.ceti.Command command = null; de.tudresden.inf.st.ceti.Command command = null;
try { try {
......
...@@ -276,17 +276,37 @@ aspect Computation { ...@@ -276,17 +276,37 @@ aspect Computation {
return new Wait(); return new Wait();
} }
syn Operation WorldModelB.lastOperationFor(Robot robot) {
if (robot == null) {
return null;
}
for (int index = getNumExecutedOperation() - 1; index >= 0; index--) {
Operation op = getExecutedOperation(index);
if (robot.equals(op.getRobotToExecute())) {
return op;
}
}
return null;
}
syn nta ErrorOperation WorldModelB.errorNoOperationComputed() = new ErrorOperation().setErrorMessage("No operation computed!");
syn nta ErrorOperation WorldModelB.errorDuplicateOperation() = new ErrorOperation().setErrorMessage("Do not send duplicate operation twice!");
syn nta ErrorOperation WorldModelB.errorNoExecutableOperation() = new ErrorOperation().setErrorMessage("No executable operation found!");
//--- getNextOperation --- //--- getNextOperation ---
syn Operation WorldModelB.getNextOperation() { syn Operation WorldModelB.getNextOperation() {
if (diffToOperations().getNumChild() == 0) { if (diffToOperations().getNumChild() == 0) {
return new ErrorOperation().setErrorMessage("No operation computed!"); return errorNoOperationComputed();
} }
for (Operation op : diffToOperations()) { for (Operation op : diffToOperations()) {
Robot executingRobot = op.getRobotToExecute();
if (!op.isErrorOperation()) { if (!op.isErrorOperation()) {
if (op.equals(lastOperationFor(executingRobot))) {
return errorDuplicateOperation();
}
return op; return op;
} }
} }
return new ErrorOperation().setErrorMessage("No executable operation found!"); return errorNoExecutableOperation();
} }
//--- canReach --- //--- canReach ---
...@@ -427,7 +447,41 @@ aspect Navigation { ...@@ -427,7 +447,41 @@ aspect Navigation {
syn boolean Operation.isErrorOperation() = false; syn boolean Operation.isErrorOperation() = false;
eq ErrorOperation.isErrorOperation() = true; eq ErrorOperation.isErrorOperation() = true;
syn Region LogicalRegion.realRegion() = worldModelB().findRegion(getName()); syn boolean Operation.isPickAndPlace() = false;
eq PickAndPlace.isPickAndPlace() = true;
syn boolean Operation.isConfigChange() = false;
eq ConfigChange.isConfigChange() = true;
syn boolean Operation.isEvacuate() = false;
eq Evacuate.isEvacuate() = true;
syn ErrorOperation Operation.asErrorOperation() = null;
eq ErrorOperation.asErrorOperation() = this;
syn PickAndPlace Operation.asPickAndPlace() = null;
eq PickAndPlace.asPickAndPlace() = this;
syn ConfigChange Operation.asConfigChange() = null;
eq ConfigChange.asConfigChange() = this;
syn Evacuate Operation.asEvacuate() = null;
eq Evacuate.asEvacuate() = this;
syn Region LogicalRegion.realRegion() {
if (hasWorldModelB()) {
return worldModelB().findRegion(getName());
}
return new Region().setName("unknown region for " + getName());
}
private boolean LogicalRegion.hasWorldModelB() {
ASTNode parent = getParent();
while (parent.getParent() != null) {
parent = parent.getParent();
}
return parent instanceof WorldModelB;
}
//--- allMappings --- //--- allMappings ---
// inh LocationMapping LogicalDropOffLocation.allMappings(); // inh LocationMapping LogicalDropOffLocation.allMappings();
...@@ -458,7 +512,9 @@ aspect Navigation { ...@@ -458,7 +512,9 @@ aspect Navigation {
syn List<String> Robot.occupiedCollaborationZonesAsList() = arrayAsList(getOccupiedCollaborationZoneNames()); syn List<String> Robot.occupiedCollaborationZonesAsList() = arrayAsList(getOccupiedCollaborationZoneNames());
eq Region.locationList() { eq Region.locationList() {
List<DropOffLocation> result = new ArrayList<>(); List<DropOffLocation> result = new ArrayList<>();
if (!worldModelB().hasMyScene()) { return result; } if (!worldModelB().hasMyScene()) {
return result;
}
for (String locationName : locationNamesAsList()) { for (String locationName : locationNamesAsList()) {
result.add(worldModelB().getMyScene().resolveObjectOfInterest(locationName).asDropOffLocation()); result.add(worldModelB().getMyScene().resolveObjectOfInterest(locationName).asDropOffLocation());
} }
...@@ -485,7 +541,8 @@ aspect GlueForShared { ...@@ -485,7 +541,8 @@ aspect GlueForShared {
inh LogicalObjectOfInterest Difference.resolveLogicalObjectOfInterest(String name); inh LogicalObjectOfInterest Difference.resolveLogicalObjectOfInterest(String name);
eq WorldModelB.diffScenes().resolveLogicalObjectOfInterest(String name) = getMyScene().getLogicalScene().resolveLogicalObjectOfInterest(name); eq WorldModelB.diffScenes().resolveLogicalObjectOfInterest(String name) = getMyScene().getLogicalScene().resolveLogicalObjectOfInterest(name);
class WorldModelB implements de.tudresden.inf.st.ros3rag.common.SharedMainParts.WorldModelWrapper {} class WorldModelB implements de.tudresden.inf.st.ros3rag.common.SharedMainParts.WorldModelWrapper {
}
eq WorldModelB.getMyScene().regionList() = getRegionList(); eq WorldModelB.getMyScene().regionList() = getRegionList();
} }
...@@ -543,6 +600,35 @@ aspect DumpAst { ...@@ -543,6 +600,35 @@ aspect DumpAst {
} }
} }
aspect Comparison {
boolean Operation.equals(Operation other) { return false; }
boolean PickAndPlace.equals(Operation other) {
if (other == null || !other.isPickAndPlace()) {
return false;
}
PickAndPlace otherPickAndPlace = other.asPickAndPlace();
return getRobotToExecute().equals(otherPickAndPlace.getRobotToExecute()) &&
getObjectToPick().getName().equals(otherPickAndPlace.getObjectToPick().getName()) &&
getTargetLocation().getName().equals(otherPickAndPlace.getTargetLocation().getName());
}
boolean ConfigChange.equals(Operation other) {
if (other == null || !other.isConfigChange()) {
return false;
}
ConfigChange otherConfigChange = other.asConfigChange();
return getRobotToExecute().equals(otherConfigChange.getRobotToExecute()) &&
getCollaborationZone().getName().equals(otherConfigChange.getCollaborationZone().getName());
}
boolean Evacuate.equals(Operation other) {
if (other == null || !other.isEvacuate()) {
return false;
}
Evacuate otherEvacuate = other.asEvacuate();
return getRobotToExecute().equals(otherEvacuate.getRobotToExecute()) &&
getCollaborationZone().getName().equals(otherEvacuate.getCollaborationZone().getName());
}
}
aspect Resolving { aspect Resolving {
//--- findRobot --- //--- findRobot ---
public Optional<Robot> WorldModelB.findRobot(String name) { public Optional<Robot> WorldModelB.findRobot(String name) {
......
...@@ -44,13 +44,20 @@ public class MainB extends SharedMainParts<MqttHandler, WorldModelB> { ...@@ -44,13 +44,20 @@ public class MainB extends SharedMainParts<MqttHandler, WorldModelB> {
@Override @Override
protected void createSpecificMainHandlerConnections() { protected void createSpecificMainHandlerConnections() {
mainHandler.newConnection("place-b/demo", bytes -> { mainHandler.newConnection("place-b/demo", bytes -> {
String topic = new String(bytes); String command = new String(bytes);
int colonIndex = command.indexOf(":");
if (colonIndex == -1) {
logger.error("Unknown demo command {}", command);
return;
}
String key = command.substring(0, colonIndex);
String value = command.substring(colonIndex + 1);
int slashIndex; int slashIndex;
switch (topic) { switch (key) {
case "objectRed1/red": case "scene":
UtilB.updatePositionOfObjectToLocation(model.getMyScene(), "objectRed1", "binRed"); if (!value.equals("initial")) {
break; logger.warn("Can only send initial scene, but got {}. Sending initial scene.", command);
case "initial_scene": }
try { try {
demo_scene = Util.readScene(UtilB.pathToDirectoryOfPlaceB().resolve("src/main/resources/config-scene-b-placeworld-manual.json")); demo_scene = Util.readScene(UtilB.pathToDirectoryOfPlaceB().resolve("src/main/resources/config-scene-b-placeworld-manual.json"));
mainHandler.publish(config.forB.topicsSceneUpdate.get(0), demo_scene.toByteArray()); mainHandler.publish(config.forB.topicsSceneUpdate.get(0), demo_scene.toByteArray());
...@@ -58,33 +65,17 @@ public class MainB extends SharedMainParts<MqttHandler, WorldModelB> { ...@@ -58,33 +65,17 @@ public class MainB extends SharedMainParts<MqttHandler, WorldModelB> {
e.printStackTrace(); e.printStackTrace();
} }
break; break;
case "arm1/idle": case "robot":
case "arm1/picking": slashIndex = value.indexOf("/");
case "arm1/placing": String robot = value.substring(0, slashIndex);
case "arm1/moving": String stateString = "STATE_" + value.substring(slashIndex + 1).toUpperCase();
case "arm2/idle":
case "arm2/picking":
case "arm2/placing":
case "arm2/moving":
slashIndex = topic.indexOf("/");
String robot = topic.substring(0, slashIndex);
String stateString = "STATE_" + topic.substring(slashIndex + 1).toUpperCase();
Object.State state = Object.State.valueOf(stateString); Object.State state = Object.State.valueOf(stateString);
updateAndPublishScene(robot, r -> r.toBuilder().setState(state).build()); updateAndPublishScene(robot, r -> r.toBuilder().setState(state).build());
break; break;
case "bigBlue/cz1": case "object":
case "bigBlue/G1": slashIndex = value.indexOf("/");
case "bigBlue/G2": String obj = value.substring(0, slashIndex);
case "bigBlue/I1": String location = value.substring(slashIndex + 1);
case "bigBlue/I2":
case "bigGreen/cz1":
case "bigGreen/G1":
case "bigGreen/G2":
case "bigGreen/I1":
case "bigGreen/I2":
slashIndex = topic.indexOf("/");
String obj = topic.substring(0, slashIndex);
String location = topic.substring(slashIndex + 1);
Position pos = model.getMyScene().resolveObjectOfInterest(location).asDropOffLocation().getPosition(); Position pos = model.getMyScene().resolveObjectOfInterest(location).asDropOffLocation().getPosition();
updateAndPublishScene(obj, o -> { updateAndPublishScene(obj, o -> {
Object.Builder builder = o.toBuilder(); Object.Builder builder = o.toBuilder();
...@@ -96,7 +87,7 @@ public class MainB extends SharedMainParts<MqttHandler, WorldModelB> { ...@@ -96,7 +87,7 @@ public class MainB extends SharedMainParts<MqttHandler, WorldModelB> {
}); });
break; break;
default: default:
logger.error("Unknown demo command {}", topic); logger.error("Unknown demo command {}", command);
} }
}); });
} }
...@@ -171,6 +162,7 @@ public class MainB extends SharedMainParts<MqttHandler, WorldModelB> { ...@@ -171,6 +162,7 @@ public class MainB extends SharedMainParts<MqttHandler, WorldModelB> {
@Override @Override
protected String getModelInfos(WorldModelB worldModelB, boolean detailed) { protected String getModelInfos(WorldModelB worldModelB, boolean detailed) {
// Thread t = new Thread(() -> {
try { try {
String filename = model.dumpAst(builder -> { String filename = model.dumpAst(builder -> {
builder.excludeChildren("Orientation", "Size"); builder.excludeChildren("Orientation", "Size");
...@@ -183,6 +175,9 @@ public class MainB extends SharedMainParts<MqttHandler, WorldModelB> { ...@@ -183,6 +175,9 @@ public class MainB extends SharedMainParts<MqttHandler, WorldModelB> {
} catch (Exception e) { } catch (Exception e) {
logger.catching(e); logger.catching(e);
} }
// });
// t.setDaemon(true);
// t.start();
return UtilB.getModelInfos(model, detailed); return UtilB.getModelInfos(model, detailed);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment