Skip to content
Snippets Groups Projects
Commit 76f56d54 authored by Sebastian Ebert's avatar Sebastian Ebert
Browse files

reworked engine to v2

parent 3c405fe4
No related branches found
No related tags found
No related merge requests found
Showing
with 129 additions and 360 deletions
......@@ -83,6 +83,8 @@ aspect BalloonExecution{
String connectedReqPlaceId = null;
boolean connectedToPubPlace = false;
String connectedPubPlaceId = null;
boolean connectedResServerPlace = false;
String connectedResServerPlaceId = null;
// place a token in each outgoing place
for(Place place:outgoingPlaces){
......@@ -101,8 +103,14 @@ aspect BalloonExecution{
if(s.equals(place.getId()) || (place.getId().startsWith(s) && place.getId().contains("-INSTANCE-"))){
connectedToPubPlace = true;
connectedPubPlaceId = place.getId();
}
}
}
if(node.isServerInstancePlace(place)){
connectedResServerPlace = true;
connectedResServerPlaceId = place.getId();
}
BalloonMarkedPlace bmp=this.resolveBalloonPlace(place);
......@@ -124,9 +132,11 @@ aspect BalloonExecution{
}
if(connectedToReqPlace){
node.notify(new DiNeRosEvent(DiNeRosEventTypes.NOTIFICATION_SERVICE_REQ, connectedReqPlaceId));
node.notify(new DiNeRosEvent(DiNeRosEventTypes.NOTIFICATION_SERVICE_REQ_CLIENT, connectedReqPlaceId));
} else if(connectedToPubPlace){
node.notify(new DiNeRosEvent(DiNeRosEventTypes.NOTIFICATION_TOPIC_PUB, connectedPubPlaceId));
} else if(connectedResServerPlace){
node.notify(new DiNeRosEvent(DiNeRosEventTypes.NOTIFICATION_SERVICE_RES_SERVER, connectedResServerPlaceId));
} else {
node.notify(new DiNeRosEvent(DiNeRosEventTypes.NOTIFICATION_MARKING_CHANGE));
}
......
......@@ -12,7 +12,7 @@ public class DiNeRosEvent {
public DiNeRosEvent(String eventType, String payload) {
if(eventType.equals(DiNeRosEventTypes.NOTIFICATION_MARKING_CHANGE) || eventType.equals(DiNeRosEventTypes.NOTIFICATION_SIGNAL_CHANGE) ||
eventType.equals(DiNeRosEventTypes.NOTIFICATION_WAIT_ENDED) || eventType.equals(DiNeRosEventTypes.NOTIFICATION_STARTUP_ENDED) ||
eventType.equals(DiNeRosEventTypes.NOTIFICATION_SERVICE_REQ) || eventType.equals(DiNeRosEventTypes.NOTIFICATION_TOPIC_PUB)) {
eventType.equals(DiNeRosEventTypes.NOTIFICATION_SERVICE_REQ_CLIENT) || eventType.equals(DiNeRosEventTypes.NOTIFICATION_TOPIC_PUB)) {
this.eventType = eventType;
} else {
throw new RuntimeException("Invalid event type used!");
......
......@@ -6,6 +6,7 @@ public class DiNeRosEventTypes {
public static final String NOTIFICATION_SIGNAL_CHANGE = "signalChange";
public static final String NOTIFICATION_WAIT_ENDED = "waitEnded";
public static final String NOTIFICATION_STARTUP_ENDED = "startEnded";
public static final String NOTIFICATION_SERVICE_REQ = "serviceReq";
public static final String NOTIFICATION_SERVICE_REQ_CLIENT = "serviceReq";
public static final String NOTIFICATION_SERVICE_RES_SERVER = "serviceRes";
public static final String NOTIFICATION_TOPIC_PUB = "topicPub";
}
package de.tudresden.inf.st.pnml.engine.ros;
import de.tudresden.inf.st.pnml.jastadd.model.BalloonCallbackStorage;
import de.tudresden.inf.st.pnml.jastadd.model.BalloonMarking;
import de.tudresden.inf.st.pnml.jastadd.model.InputSignalConnector;
import de.tudresden.inf.st.pnml.jastadd.model.PetriNet;
public class DiNeRosDefaultServer implements DiNeRosServer{
@Override
public boolean execute(BalloonMarking balloonMarking, BalloonCallbackStorage balloonCallbackStorage, PetriNet petriNet,
String subnet, InputSignalConnector inputSignalConnector, DiNeRosNode node) {
return DiNeRosNodeUtil.defaultSubNetExecute(balloonMarking, balloonCallbackStorage, petriNet, subnet, inputSignalConnector, node);
}
}
......@@ -5,6 +5,7 @@ import de.tudresden.inf.st.pnml.base.data.ClauseValuesDefinition;
import de.tudresden.inf.st.pnml.engine.event.DiNeRosEvent;
import de.tudresden.inf.st.pnml.engine.event.DiNeRosEventTypes;
import de.tudresden.inf.st.pnml.engine.transform.PetriNetInitializer;
import de.tudresden.inf.st.pnml.engine.transform.ServiceInstanceUtil;
import de.tudresden.inf.st.pnml.jastadd.model.*;
import org.jetbrains.annotations.NotNull;
import org.ros.concurrent.CancellableLoop;
......@@ -14,6 +15,7 @@ import org.ros.namespace.GraphName;
import org.ros.node.AbstractNodeMain;
import org.ros.node.ConnectedNode;
import org.ros.node.service.ServiceClient;
import org.ros.node.service.ServiceResponseBuilder;
import org.ros.node.service.ServiceResponseListener;
import org.ros.node.topic.Publisher;
import org.ros.node.topic.Subscriber;
......@@ -40,6 +42,8 @@ public abstract class DiNeRosNode extends AbstractNodeMain {
private final Map<DinerosPlace, Subscriber> dinerosSubscribers = new HashMap<>();
private final Map<DinerosPlace, Publisher<String>> dinerosPublishers = new HashMap<>();
private final Map<java.lang.String, java.lang.String> responsePlaceToInstance = new HashMap<>();
private final Set<java.lang.String> activeServerInstances = new HashSet<>();
public DiNeRosNode(java.lang.String nodeName, PetriNet petriNet, java.lang.String rcHost, java.lang.String gcProtocol) {
this.nodeName = nodeName;
......@@ -100,12 +104,15 @@ public abstract class DiNeRosNode extends AbstractNodeMain {
case DiNeRosEventTypes.NOTIFICATION_STARTUP_ENDED:
onStartupEndedInternal(signalFilteredTransitions);
break;
case DiNeRosEventTypes.NOTIFICATION_SERVICE_REQ:
case DiNeRosEventTypes.NOTIFICATION_SERVICE_REQ_CLIENT:
onServiceRequestAvailableOnClientSide(event.payload);
break;
case DiNeRosEventTypes.NOTIFICATION_TOPIC_PUB:
onTopicPublisherAvailable(event.payload);
break;
case DiNeRosEventTypes.NOTIFICATION_SERVICE_RES_SERVER:
onServiceResponseAvailableOnServerSide(event.payload);
break;
}
}
......@@ -125,6 +132,16 @@ public abstract class DiNeRosNode extends AbstractNodeMain {
}
private void onServiceResponseAvailableOnServerSide(java.lang.String placeId) {
for(Map.Entry<java.lang.String, java.lang.String> entry : responsePlaceToInstance.entrySet()){
if(entry.getKey().equals(placeId)){
activeServerInstances.remove(entry.getValue());
return;
}
}
}
private void onServiceRequestAvailableOnClientSide(java.lang.String placeId) {
ServiceClient<StringServiceRequest, StringServiceResponse> serviceClient;
......@@ -275,8 +292,61 @@ public abstract class DiNeRosNode extends AbstractNodeMain {
System.out.println("[INIT NODE] Initializing node: " + nodeName);
// init service servers (deep copies)
// TODO
// init service servers mechanism
// is a 1:1 mapping, because there is always just on server
HashMap<java.lang.String, ArrayList<java.lang.String>> channelServerReqElementMap
= petriNet.getChannelElemensByKey(PnmlConstants.CHANNEL_PLACE_TYPE_SERVER_REQ_KEY);
for (java.lang.String key : channelServerReqElementMap.keySet()) {
connectedNode.newServiceServer(key, StringService._TYPE,
(ServiceResponseBuilder<StringServiceRequest, StringServiceResponse>) (request, response) -> {
java.lang.String instanceId = UUID.randomUUID().toString().replace("-", "");
// create a suffixed deep copy
for (Page p : petriNet.allPages()) {
if (p.getServiceName() != null && p.getServiceName().equals(key)) {
Page copy = p.treeCopy();
ServiceInstanceUtil.updateInstanceIds(copy, "-INSTANCE-" + instanceId);
copy.setId(p.getId() + "-INSTANCE-" + instanceId);
copy.getName().setText(copy.getId());
petriNet.addPage(copy);
petriNet.flushTreeCache();
petriNet.flushCollectionCache();
break;
}
}
HashMap<java.lang.String, ArrayList<java.lang.String>> channelServerResElementMap
= petriNet.getChannelElemensByKey(PnmlConstants.CHANNEL_PLACE_TYPE_SERVER_RES_KEY);
for (java.lang.String resKey : channelServerResElementMap.keySet()) {
if (resKey.equals(key)) {
responsePlaceToInstance.put(channelServerResElementMap.
get(resKey).get(0) + "-INSTANCE-" + instanceId, instanceId);
activeServerInstances.add(instanceId);
Place instanceEntryPlace = petriNet.getPlaceById(channelServerResElementMap.
get(resKey).get(0) + "-INSTANCE-" + instanceId);
marking.resolveBalloonPlace(instanceEntryPlace).addBalloonMarking(new BalloonToken(request.getInput()));
this.notify(new DiNeRosEvent(DiNeRosEventTypes.NOTIFICATION_MARKING_CHANGE));
break;
}
}
while(activeServerInstances.contains(instanceId)){}
for(Map.Entry<java.lang.String, java.lang.String> entry : responsePlaceToInstance.entrySet()){
if(entry.getValue().equals(instanceId)){
// set response value based on output token
response.setOutput(marking.resolveBalloonPlace(petriNet.
getPlaceById(entry.getKey())).getBalloonMarking(0).getValue());
responsePlaceToInstance.remove(entry.getKey());
break;
}
}
ServiceInstanceUtil.removeServiceServerInstance(petriNet, key + "-INSTANCE-" + instanceId);
});
}
// init publishers
HashMap<java.lang.String, ArrayList<java.lang.String>> channelPubElementMap
......@@ -329,34 +399,7 @@ public abstract class DiNeRosNode extends AbstractNodeMain {
return null;
}
public List<Transition> getSubnetTransitionsByIds(List<java.lang.String> ids, PetriNet petriNet) {
List<Transition> transitions = new ArrayList<>();
for (java.lang.String id : ids) {
for (Transition t : petriNet.allTransitions()) {
if (t.getId().equals(id)) {
transitions.add(t);
}
}
}
return transitions;
}
public List<Place> getSubnetPlacesByIds(List<java.lang.String> ids, PetriNet petriNet) {
List<Place> places = new ArrayList<>();
for (java.lang.String id : ids) {
for (Place p : petriNet.allPlaces()) {
if (p.getId().equals(id)) {
places.add(p);
}
}
}
return places;
public boolean isServerInstancePlace(Place place) {
return responsePlaceToInstance.containsKey(place);
}
}
\ No newline at end of file
package de.tudresden.inf.st.pnml.engine.ros;
import de.tudresden.inf.st.pnml.jastadd.model.BalloonCallbackStorage;
import de.tudresden.inf.st.pnml.jastadd.model.BalloonMarking;
import de.tudresden.inf.st.pnml.jastadd.model.InputSignalConnector;
import de.tudresden.inf.st.pnml.jastadd.model.PetriNet;
public interface DiNeRosServer {
boolean execute(BalloonMarking balloonMarking, BalloonCallbackStorage balloonCallbackStorage,
PetriNet petriNet, String subnet, InputSignalConnector inputSignalConnector, DiNeRosNode node);
}
package de.tudresden.inf.st.pnml.engine.ros;
import de.tudresden.inf.st.pnml.jastadd.model.BalloonCallbackStorage;
import de.tudresden.inf.st.pnml.jastadd.model.BalloonMarking;
import de.tudresden.inf.st.pnml.jastadd.model.InputSignalConnector;
import de.tudresden.inf.st.pnml.jastadd.model.PetriNet;
public interface DiNeRosSubscriber {
boolean execute(BalloonMarking balloonMarking, BalloonCallbackStorage balloonCallbackStorage, PetriNet petriNet,
String subnet, InputSignalConnector inputSignalConnector, DiNeRosNode node);
}
package de.tudresden.inf.st.pnml.engine.ros;
import de.tudresden.inf.st.pnml.jastadd.model.BalloonMarking;
import de.tudresden.inf.st.pnml.jastadd.model.PetriNet;
import de.tudresden.inf.st.pnml.jastadd.model.Transition;
import org.ros.node.ConnectedNode;
import org.ros.node.topic.Publisher;
import org.ros.node.topic.Subscriber;
import std_msgs.String;
import java.nio.charset.StandardCharsets;
import java.util.function.BiConsumer;
import org.ros.message.MessageListener;
public class RosCommunicationUtil {
......
package de.tudresden.inf.st.pnml.engine.transform;
import de.tudresden.inf.st.pnml.jastadd.model.*;
public class ServiceInstanceUtil {
public static void updateInstanceIds(Page page, String suffix){
for(PnObject pnObject : page.getObjects()){
pnObject.setId(pnObject.getId() + suffix);
pnObject.getName().setText(pnObject.getId());
if(pnObject.isPageNode()){
updateInstanceIds(pnObject.asPage(), suffix);
}
}
}
public static void removeServiceServerInstance(PetriNet petriNet, String pageId){
for(Page page : petriNet.allPages()){
if(page.getId().equals(pageId)) {
page.removeSelf();
petriNet.flushTreeCache();
petriNet.flushCollectionCache();
}
}
}
}
package de.tudresden.inf.st.pnml.engine.transform;
import de.tudresden.inf.st.pnml.base.constants.PnmlConstants;
import de.tudresden.inf.st.pnml.jastadd.model.*;
import java.util.*;
public class ServiceTransformer {
public static DinerosPlace includeServerInstance(PetriNet petriNet, String subnet, String suffix, List<String> addedElementIds){
Page topPage = petriNet.getPage(0);
DinerosPlace serverInputPlace = null;
// Elements
for (Place p : getPlacesBySubnet(petriNet, subnet)) {
DinerosPlace copy = getDinerosPlace();
assert copy != null;
copy.setId(p.getId() + "-" + suffix);
copy.setToolspecificList(p.getToolspecificList().treeCopy());
copy.getName().setText(p.getName().getText());
if(p.getNodeGraphics() != null) {
copy.setNodeGraphics(p.getNodeGraphics().treeCopy());
}
// copy initial marking of places
PTMarking m = new PTMarking();
m.setText(p.getInitialMarking().getText());
PlaceInformation pi = new PlaceInformation();
pi.setSubNet(p.asDinerosPlace().getStaticPlaceInformation().getSubNet() + "-" + suffix);
pi.setNode(p.asDinerosPlace().getStaticPlaceInformation().getNode());
copy.setMutablePlaceInformation(pi);
topPage.addObject(copy);
addedElementIds.add(copy.getId());
for( Map.Entry<String, String> entry : petriNet.getCommunicatorInformation().getCommunicatorMapping().entries()){
if(entry.getKey().equals(p.getId()) && entry.getValue().equals(PnmlConstants.SERVICE_SERVER)){
serverInputPlace = p.asDinerosPlace();
}
}
}
petriNet.flushTreeCache();
// TODO: Reference Transitions
for(RefPlace rp : getRefPlaceBySubnet(petriNet, subnet)){
RefPlace copy = new RefPlace();
copy.setName(rp.getName().treeCopy());
copy.setId(rp.getId() + "-" + suffix);
if(rp.getNodeGraphics() != null) {
copy.setNodeGraphics(rp.getNodeGraphics().treeCopy());
}
copy.setToolspecificList(rp.getToolspecificList().treeCopy());
String refId = rp.getRef().getId() + "-" + suffix;
copy.setRef(getPlaceNodeById(petriNet, refId));
topPage.addObject(copy);
addedElementIds.add(copy.getId());
}
petriNet.flushTreeCache();
for (Transition t : getTransitionsBySubnet(petriNet, subnet)) {
DinerosTransition copy = getInputSignalTransition();
assert copy != null;
copy.setId(t.getId() + "-" + suffix);
copy.getName().setText(t.getName().getText());
SignalTransitionInformation sti = new SignalTransitionInformation();
sti.setNode(t.asDinerosTransition().getStaticTransitionInformation().getNode());
sti.setSubNet(t.asDinerosTransition().getStaticTransitionInformation().getSubNet() + "-" + suffix);
//sti.setClause(t.asDinerosTransition().getStaticTransitionInformation().asSignalTransitionInformation().getClause().deepCopy());
copy.setMutableTransitionInformation(sti);
copy.getName().setText(t.getName().getText());
copy.setToolspecificList(t.getToolspecificList().treeCopy());
if(t.getNodeGraphics() != null) {
copy.setNodeGraphics(t.getNodeGraphics().treeCopy());
}
PetriNetInitializer.initMutableTransitionInformation(suffix, t, copy);
topPage.addObject(copy);
addedElementIds.add(copy.getId());
}
petriNet.flushTreeCache();
// Arcs
for (Arc a : getInnerAndBorderSubnetArcs(petriNet, subnet)) {
Arc newArc = a.treeCopy();
String sourceId = a.getSource().getId() + "-" + suffix;
newArc.setSource((Node) getPnObjectByID(petriNet, sourceId));
String targetId = a.getTarget().getId() + "-" + suffix;
if(a.getTarget().isTransitionNode()){
if(!a.getTarget().asTransitionNode().asTransition().asDinerosTransition().getStaticTransitionInformation().getSubNet().equals(subnet)){
targetId = a.getTarget().getId();
}
}
if(a.getTarget().isPlaceObject()){
if(!a.getTarget().asPlaceNode().asPlace().asDinerosPlace().getStaticPlaceInformation().getSubNet().equals(subnet)){
targetId = a.getTarget().getId();
}
}
if(a.getTarget().asRefPlace() != null){
if(!a.getTarget().asRefPlace().getSubNet().equals(subnet)){
targetId = a.getTarget().getId();
}
}
newArc.setTarget((Node) getPnObjectByID(petriNet, targetId));
newArc.setId(sourceId + "-to-" + targetId);
topPage.addObject(newArc);
addedElementIds.add(newArc.getId());
}
petriNet.flushTreeCache();
return serverInputPlace;
}
public static PetriNet removeServiceServerInstance(PetriNet petriNet, List<String> addedElementIds){
for(String id : addedElementIds){
Objects.requireNonNull(getPnObjectByID(petriNet, id)).removeSelf();
}
petriNet.flushTreeCache();
return petriNet;
}
private static Set<Arc> getInnerAndBorderSubnetArcs(PetriNet petriNet, String subnet) {
Set<Arc> arcs = new HashSet<>();
for (Arc a : petriNet.allArcs()) {
if(a.getTarget().isTransitionNode() && a.getSource().isPlaceNode()){
if(a.getSource().asPlaceNode().asPlace().asDinerosPlace().getStaticPlaceInformation().getSubNet().equals(subnet)){
arcs.add(a);
}
} else {
if(a.getSource().asTransitionNode().asTransition().asDinerosTransition().getStaticTransitionInformation().getSubNet().equals(subnet)){
arcs.add(a);
}
}
}
return arcs;
}
private static DinerosTransition getInputSignalTransition(){
PetriNet templateNet = PnmlParser.parsePnml(System.getProperty("user.dir") + "/src/main/resources/elements/InputSignalTransition.pnml").get(0);
for(Transition t : templateNet.allTransitions()){
if(t.getId().equals("InputSignalTransition")){
return t.asDinerosTransition();
}
}
return null;
}
private static DinerosPlace getDinerosPlace(){
PetriNet templateNet = PnmlParser.parsePnml(System.getProperty("user.dir") + "/src/main/resources/elements/OutputSignalPlace.pnml").get(0);
for(Place p : templateNet.allPlaces()){
if(p.getId().equals("OutputSignalPlace")){
return p.asDinerosPlace();
}
}
return null;
}
private static PnObject getPnObjectByID(PetriNet petriNet, String Id) {
for (PnObject po : petriNet.allObjects()) {
if (po.getId().equals(Id)) {
return po;
}
}
return null;
}
private static Set<Place> getPlacesBySubnet(PetriNet petriNet, String subnet) {
Set<Place> places = new HashSet<>();
for (Place p : petriNet.allPlaces()) {
if (p.asDinerosPlace().getStaticPlaceInformation().getSubNet().equals(subnet)) {
places.add(p);
}
}
return places;
}
private static Set<Transition> getTransitionsBySubnet(PetriNet petriNet, String subnet) {
Set<Transition> transitions = new HashSet<>();
for (Transition t : petriNet.allTransitions()) {
// System.out.println(t.getId() + " +++ " + t.asDinerosTransition().getStaticTransitionInformation().getSubNet() + " +++ " + t.asDinerosTransition().getStaticTransitionInformation().getType());
if (t.asDinerosTransition().getStaticTransitionInformation().getSubNet().equals(subnet)) {
transitions.add(t);
}
}
return transitions;
}
private static Set<RefPlace> getRefPlaceBySubnet(PetriNet petriNet, String subnet) {
Set<RefPlace> places = new HashSet<>();
for (RefPlace rp : petriNet.allRefPlaces()) {
if (rp.getSubNet().equals(subnet)) {
places.add(rp);
}
}
return places;
}
private static Set<RefTransition> getRefTransitionBySubnet(PetriNet petriNet, String subnet) {
Set<RefTransition> transitions = new HashSet<>();
for (RefTransition rt : petriNet.allRefTransitions()) {
if (rt.getSubNet().equals(subnet)) {
transitions.add(rt);
}
}
return transitions;
}
private static PlaceNode getPlaceNodeById(PetriNet petriNet, String id) {
for (PlaceNode p : petriNet.allPlaceNodes()) {
if (p.getId().equals(id)) {
return p;
}
}
return null;
}
}
......@@ -9,7 +9,9 @@
<ports>
<port name="topicP1" placeType="sub" limit="5">p1</port>
<port name="serviceP1" placeType="creq" cResponsePlace="p2">p1</port>
<port name="serviceP1" placeType="cres" cRequestPlace="p1">p1</port>
<port name="serviceP1" placeType="cres" cRequestPlace="p1">p2</port>
<port name="serviceP1" placeType="sreq" sResponsePlace="p4">p3</port>
<port name="serviceP1" placeType="sres" sRequestPlace="p3">p4</port>
</ports>
</toolspecific>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment