From e990ce6ce1f50d5928b6984482b6cdcbc98d93c5 Mon Sep 17 00:00:00 2001 From: SebastianEbert <sebastian.ebert@tu-dresden.de> Date: Mon, 2 Dec 2024 16:30:11 +0100 Subject: [PATCH] coding solutions --- .../de/tudresden/inf/st/sorting/Main.java | 9 ---- .../st/sorting/constants/TokenConstants.java | 2 + .../inf/st/sorting/fake/FakeServerNode.java | 44 ------------------- .../sorting/handlers/ControlEndHandler.java | 18 +++++++- .../inf/st/sorting/handlers/PickHandler.java | 4 ++ .../sorting/handlers/PickSuccessHandler.java | 17 +++++++ .../handlers/SensorDataProcessingHandler.java | 44 ++++++++++++++----- .../sorting/handlers/ShowResultHandler.java | 5 +++ .../st/sorting/handlers/SortColorHandler.java | 30 +++++++++++++ .../inf/st/sorting/mqtt/MessageCallback.java | 7 +++ .../inf/st/sorting/mqtt/MessageListener.java | 37 ++++++++++++++++ .../src/main/resources/nets/SelectorNode.pnml | 9 ++-- 12 files changed, 158 insertions(+), 68 deletions(-) delete mode 100644 case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/fake/FakeServerNode.java create mode 100644 case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/mqtt/MessageCallback.java create mode 100644 case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/mqtt/MessageListener.java diff --git a/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/Main.java b/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/Main.java index f25ada3..d01d46c 100644 --- a/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/Main.java +++ b/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/Main.java @@ -1,9 +1,6 @@ package de.tudresden.inf.st.sorting; -import de.tudresden.inf.st.sorting.fake.FakeServerNode; -import org.ros.node.DefaultNodeMainExecutor; import org.ros.node.NodeConfiguration; -import org.ros.node.NodeMainExecutor; import java.net.URI; @@ -13,15 +10,9 @@ public class Main { private static final String ROS_MASTER_URI = "http://localhost:11311"; private static final NodeConfiguration nodeConfiguration = NodeConfiguration.newPublic(ROS_HOST); - private static final NodeMainExecutor nodeMainExecutor = DefaultNodeMainExecutor.newDefault(); public static void main(java.lang.String[] args) { nodeConfiguration.setMasterUri(URI.create(ROS_MASTER_URI)); - - // FAKE NODES FOR TESTING - new Thread(() -> nodeMainExecutor.execute(new FakeServerNode("pickService", "PickServiceNode"), nodeConfiguration)) {{start();}}; - new Thread(() -> nodeMainExecutor.execute(new FakeServerNode("placeService", "PlaceServiceNode"), nodeConfiguration)) {{start();}}; - } } diff --git a/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/constants/TokenConstants.java b/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/constants/TokenConstants.java index 7be0979..c267821 100644 --- a/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/constants/TokenConstants.java +++ b/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/constants/TokenConstants.java @@ -10,5 +10,7 @@ public final class TokenConstants { public static final String NAME = "name"; public static final String TRACE = "trace"; public static final String LOCKED = "locked"; + public static final String ROBOT = "robot"; + public static final String TIME_PICK = "pickTime"; } diff --git a/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/fake/FakeServerNode.java b/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/fake/FakeServerNode.java deleted file mode 100644 index c4308b0..0000000 --- a/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/fake/FakeServerNode.java +++ /dev/null @@ -1,44 +0,0 @@ -package de.tudresden.inf.st.sorting.fake; - -import org.ros.namespace.GraphName; -import org.ros.node.AbstractNodeMain; -import org.ros.node.ConnectedNode; -import org.ros.node.service.ServiceResponseBuilder; -import rosjava_srv.StringService; -import rosjava_srv.StringServiceRequest; -import rosjava_srv.StringServiceResponse; - -public class FakeServerNode extends AbstractNodeMain { - - private final String serviceName; - private final String nodeName; - - public FakeServerNode(String serviceName, String nodeName) { - this.serviceName = serviceName; - this.nodeName = nodeName; - } - - @Override - public GraphName getDefaultNodeName() { - return GraphName.of(nodeName); - } - - @Override - public void onStart(final ConnectedNode connectedNode) { - - System.out.println("[" + nodeName + "] Starting node."); - - connectedNode.newServiceServer(serviceName, StringService._TYPE, - (ServiceResponseBuilder<StringServiceRequest, StringServiceResponse>) (request, response) -> { - - System.out.println("[" + nodeName + "] Service Input: \"" + request.getInput() + "\""); - try { - Thread.sleep(4000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - System.out.println("[" + nodeName + "] Finished sleep."); - response.setOutput(request.getInput()); - }); - } -} diff --git a/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/handlers/ControlEndHandler.java b/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/handlers/ControlEndHandler.java index c9f912c..f5d72ef 100644 --- a/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/handlers/ControlEndHandler.java +++ b/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/handlers/ControlEndHandler.java @@ -3,6 +3,8 @@ package de.tudresden.inf.st.sorting.handlers; import de.tudresden.inf.st.pnml.engine.execution.TransitionHandler; import de.tudresden.inf.st.sorting.constants.TokenConstants; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Function; @@ -20,7 +22,21 @@ public class ControlEndHandler extends TransitionHandler { } } - return maps; + // TASK 1.2 START // + List<Map<String, Object>> out = new ArrayList<>(); + + for(Map<String, Object> m : maps) { + for (Map.Entry<String, Object> entry : m.entrySet()) { + if (entry.getKey().equals(TokenConstants.TRACE)) { + if(String.valueOf(entry.getValue()).endsWith("pickSuccess")){ + out.add(m); + } + } + } + } + + return out.isEmpty() ? maps : out; + // TASK 1.2 END // }; public ControlEndHandler(int priority) { diff --git a/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/handlers/PickHandler.java b/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/handlers/PickHandler.java index a826857..f3a144a 100644 --- a/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/handlers/PickHandler.java +++ b/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/handlers/PickHandler.java @@ -28,6 +28,10 @@ public class PickHandler extends TransitionHandler { m.replace(TokenConstants.TRACE, oldTrace + "-pickToSafety"); res.add(m); } + + // TASK 1.2 START // + m.replace(TokenConstants.TIME_PICK, Long.toString(System.currentTimeMillis())); + // TASK 1.3 END // } return res; diff --git a/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/handlers/PickSuccessHandler.java b/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/handlers/PickSuccessHandler.java index 3f246ec..f1f4df6 100644 --- a/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/handlers/PickSuccessHandler.java +++ b/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/handlers/PickSuccessHandler.java @@ -14,6 +14,23 @@ public class PickSuccessHandler extends TransitionHandler { for (Map<String, Object> m : maps) { m.replace(TokenConstants.PICK_SUCCESS, "success"); + + + // TASK 1.2 START // + long l1 = Long.parseLong(m.get(TokenConstants.TIME_PICK).toString()); + long l2 = System.currentTimeMillis(); + long diff = l2 - l1; + m.replace(TokenConstants.TIME_PICK, String.valueOf(diff)); + + for (Map.Entry<String, Object> entry : m.entrySet()) { + if (entry.getKey().equals(TokenConstants.TRACE)) { + String oldTrace = String.valueOf(entry.getValue()); + String newTrace = oldTrace + "-" + "pickSuccess"; + m.replace(TokenConstants.TRACE, newTrace); + } + } + + // TASK 1.3 END // } return maps; diff --git a/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/handlers/SensorDataProcessingHandler.java b/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/handlers/SensorDataProcessingHandler.java index 137f0e5..7ee7c31 100644 --- a/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/handlers/SensorDataProcessingHandler.java +++ b/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/handlers/SensorDataProcessingHandler.java @@ -4,14 +4,15 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; import de.tudresden.inf.st.pnml.engine.execution.TransitionHandler; -import de.tudresden.inf.st.pnml.jastadd.model.PnmlParser; import de.tudresden.inf.st.sorting.constants.TokenConstants; +import de.tudresden.inf.st.sorting.mqtt.MessageListener; -import java.io.IOException; import java.lang.reflect.Type; -import java.nio.file.Files; import java.util.List; import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; import java.util.function.Function; public class SensorDataProcessingHandler extends TransitionHandler { @@ -19,15 +20,35 @@ public class SensorDataProcessingHandler extends TransitionHandler { final static Function<List<Map<String, Object>>, List<Map<String, Object>>> PROCESS_DATA_HANDLING_FUNCTION = maps -> { System.out.println("Executing GET_DATA_HANDLING_FUNCTION."); - try { - Map<String, Object> fakeRes = parse( - Files.readString(PnmlParser.toTempPath("/docs/FakeConfig.json"))); + MessageListener listener = new MessageListener(); + ExecutorService executor = Executors.newSingleThreadExecutor(); + executor.submit(() -> { + listener.listen(message -> { + System.out.println("Received message: " + message); + + for (Map<String, Object> m : maps) { + if (Long.parseLong(message) < 4) { + m.replace(TokenConstants.HUMAN_DETECTED, "true"); + } else { + m.replace(TokenConstants.HUMAN_DETECTED, "false"); + } + } + listener.stop(); + }); + }); - for(Map<String, Object> m : maps){ - m.replace(TokenConstants.HUMAN_DETECTED, fakeRes.get("sensor")); + // Wait for a maximum of 2 seconds + try { + if (!listener.awaitStop(2, TimeUnit.SECONDS)) { + System.out.println("Timeout reached, no message received."); + for (Map<String, Object> m : maps) { + m.replace(TokenConstants.HUMAN_DETECTED, "true"); + } } - } catch (IOException e) { - e.printStackTrace(); + } catch (InterruptedException e) { + System.err.println("Thread interrupted while waiting: " + e.getMessage()); + } finally { + executor.shutdown(); } return maps; @@ -39,7 +60,8 @@ public class SensorDataProcessingHandler extends TransitionHandler { private static Map<String, Object> parse(java.lang.String s) { Gson gson = new GsonBuilder().create(); - Type mapType = new TypeToken<Map<String, Object>>(){}.getType(); + Type mapType = new TypeToken<Map<String, Object>>() { + }.getType(); return gson.fromJson(s, mapType); } } \ No newline at end of file diff --git a/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/handlers/ShowResultHandler.java b/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/handlers/ShowResultHandler.java index 273e9bc..5c775fb 100644 --- a/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/handlers/ShowResultHandler.java +++ b/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/handlers/ShowResultHandler.java @@ -17,6 +17,11 @@ public class ShowResultHandler extends TransitionHandler { + "\n -color " + m.get(TokenConstants.COLOR) + "\n -pick " + m.get(TokenConstants.PICK_SUCCESS) + "\n -place " + m.get(TokenConstants.PLACE_SUCCESS)); + // TASK 1.2 START // + System.out.println("Picking Information" + + "\n -robot " + m.get(TokenConstants.ROBOT) + + "\n -pickTime " + m.get(TokenConstants.TIME_PICK)); + // TASK 1.2 END // } return maps; }; diff --git a/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/handlers/SortColorHandler.java b/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/handlers/SortColorHandler.java index 1cee209..47065f2 100644 --- a/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/handlers/SortColorHandler.java +++ b/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/handlers/SortColorHandler.java @@ -2,6 +2,7 @@ package de.tudresden.inf.st.sorting.handlers; import de.tudresden.inf.st.pnml.engine.execution.TransitionHandler; import de.tudresden.inf.st.sorting.constants.TokenConstants; +import org.jetbrains.annotations.NotNull; import java.util.List; import java.util.Map; @@ -11,18 +12,47 @@ public class SortColorHandler extends TransitionHandler { final static Function<List<Map<String, Object>>, List<Map<String, Object>>> SORT_HANDLING_FUNCTION = maps -> { System.out.println("Executing SORT_HANDLING_FUNCTION."); + for(Map<String, Object> m : maps){ + for (Map.Entry<String, Object> entry : m.entrySet()) { if(entry.getKey().equals(TokenConstants.TRACE)){ String oldTrace = String.valueOf(entry.getValue()); String newTrace = oldTrace + "-" + "SortColor"; m.replace(TokenConstants.TRACE, newTrace); } + + // TASK 1.1 START // + + if(entry.getKey().equals(TokenConstants.ROBOT)){ + if(getColor(m).equals("green")){ + m.replace(TokenConstants.TRACE, "right"); + } else { + m.replace(TokenConstants.TRACE, "left"); + } + } + + // TASK 1.1 END // } } return maps; }; + // TASK 1.1 START // + + private static @NotNull String getColor(Map<String, Object> m) { + String color = ""; + + for (Map.Entry<String, Object> e : m.entrySet()) { + if(e.getKey().equals(TokenConstants.COLOR)){ + color = e.getKey(); + } + } + return color; + } + + // TASK 1.1 END // + public SortColorHandler(int priority) { super(priority, SORT_HANDLING_FUNCTION); } diff --git a/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/mqtt/MessageCallback.java b/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/mqtt/MessageCallback.java new file mode 100644 index 0000000..8b29759 --- /dev/null +++ b/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/mqtt/MessageCallback.java @@ -0,0 +1,7 @@ +package de.tudresden.inf.st.sorting.mqtt; + +// Callback Interface +@FunctionalInterface +public interface MessageCallback { + void onMessage(String message); +} diff --git a/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/mqtt/MessageListener.java b/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/mqtt/MessageListener.java new file mode 100644 index 0000000..db011df --- /dev/null +++ b/case-study-sorting-pkg/src/main/java/de/tudresden/inf/st/sorting/mqtt/MessageListener.java @@ -0,0 +1,37 @@ +package de.tudresden.inf.st.sorting.mqtt; + +import java.util.concurrent.TimeUnit; +// TASK 2 START // +public class MessageListener { + + private volatile boolean running = true; + + // Simulate listening for a message + public void listen(MessageCallback callback) { + try { + // Simulate receiving a message after 1 second + Thread.sleep(1000); + if (running) { + callback.onMessage("Hello, this is a test message!"); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + System.err.println("Listener interrupted: " + e.getMessage()); + } + } + + // Stop the listener + public void stop() { + running = false; + } + + // Await until the listener stops or timeout is reached + public boolean awaitStop(long timeout, TimeUnit unit) throws InterruptedException { + long startTime = System.nanoTime(); + while (running && (System.nanoTime() - startTime) < unit.toNanos(timeout)) { + Thread.sleep(100); // Check every 100ms + } + return !running; + } +} + diff --git a/case-study-sorting-pkg/src/main/resources/nets/SelectorNode.pnml b/case-study-sorting-pkg/src/main/resources/nets/SelectorNode.pnml index c914a69..6e92f66 100644 --- a/case-study-sorting-pkg/src/main/resources/nets/SelectorNode.pnml +++ b/case-study-sorting-pkg/src/main/resources/nets/SelectorNode.pnml @@ -19,7 +19,8 @@ <balloonMarking> <tokens> <token>{"color" : "green", "name" : "green1", "pickSuccess" : "false", "placeSuccess" : "false", - "humanDetected" : "false", "sensorData" : "", "trace" : "", "locked" : "false" } </token> + "humanDetected" : "false", "sensorData" : "", "trace" : "", + "locked" : "false", "robot" : "", "pickTime" : ""} </token> </tokens> </balloonMarking> </toolspecific> @@ -51,7 +52,8 @@ <balloonMarking> <tokens> <token>{"color" : "blue", "name" : "blue1", "pickSuccess" : "false", "placeSuccess" : "false", - "humanDetected" : "false", "sensorData" : "", "trace" : "", "locked" : "false" } </token> + "humanDetected" : "false", "sensorData" : "", "trace" : "", + "locked" : "false", "robot" : "", "pickTime" : ""} </token> </tokens> </balloonMarking> </toolspecific> @@ -71,7 +73,8 @@ <balloonMarking> <tokens> <token>{"color" : "red", "name" : "red1", "pickSuccess" : "false", "placeSuccess" : "false", - "humanDetected" : "false", "sensorData" : "", "trace" : "", "locked" : "false" } </token> + "humanDetected" : "false", "sensorData" : "", "trace" : "", + "locked" : "false", "robot" : "", "pickTime" : ""} </token> </tokens> </balloonMarking> </toolspecific> -- GitLab