Browse Source

Working initial version of PDEVS simulation as a service

Yentl Van Tendeloo 7 years ago
parent
commit
56c6f79c23

+ 35 - 0
models/paralleldevs_design.mvc

@@ -0,0 +1,35 @@
+ComplexAttribute ActionCode {}
+SimpleAttribute String {}
+
+Class BaseDEVSBlock {
+    name: String
+}
+
+Class AtomicDEVSBlock: BaseDEVSBlock {
+    timeAdvance: ActionCode
+    outputFnc: ActionCode
+    intTransition: ActionCode
+    extTransition: ActionCode
+    confTransition: ActionCode
+    initialState: ActionCode
+}
+
+Class CoupledDEVSBlock: BaseDEVSBlock {}
+
+Class DEVSInstance {
+    name: String
+    type: String
+}
+
+Association SubModel(CoupledDEVSBlock, DEVSInstance) {}
+
+Class Port {
+    name: String
+}
+
+Class InputPort: Port {}
+Class OutputPort: Port {}
+
+Association DEVSBlockToPort(BaseDEVSBlock, Port) {}
+Association DEVSInstanceToPort(DEVSInstance, Port) {}
+Association Channel (Port, Port) {}

+ 151 - 0
models/pdevs_client.alc

@@ -0,0 +1,151 @@
+include "primitives.alh"
+include "services.alh"
+include "modelling.alh"
+include "object_operations.alh"
+include "utils.alh"
+include "io.alh"
+include "typing.alh"
+
+Boolean function main(model : Element):
+    log("Translating DEVS to string representation!")
+
+    String model_rep
+    Element all_atomics
+    Element curr_atomic
+    Element all_coupleds
+    Element curr_coupled
+    Element string_element
+    Element all_ports
+    Element all_submodels
+    Element curr_port
+    Element curr_submodel
+    Element out_channels
+    Element curr_channel
+    Element possible_parent
+    Element parent
+    String curr_port_name
+    String curr_port_type
+    String curr_submodel_name
+    String curr_submodel_type
+
+    model_rep = "\nfrom DEVS import *\nfrom infinity import INFINITY\n\n"
+
+    all_atomics = allInstances(model, "ParallelDEVS/AtomicDEVSBlock")
+    while (read_nr_out(all_atomics) > 0):
+        curr_atomic = set_pop(all_atomics)
+        model_rep = ((model_rep + "class ") + cast_string(read_attribute(model, curr_atomic, "name"))) + "(AtomicDEVS):\n"
+        model_rep = ((model_rep + "\tdef __init__(self, name=") + cast_value(read_attribute(model, curr_atomic, "name"))) + "):\n"
+        model_rep = model_rep + "\t\tAtomicDEVS.__init__(self, name)\n"
+        model_rep = model_rep + "\t\tself.state = self.initialState()\n"
+        model_rep = model_rep + "\t\tself.my_ports = {"
+        all_ports = allAssociationDestinations(model, curr_atomic, "ParallelDEVS/DEVSBlockToPort")
+        while (read_nr_out(all_ports) > 0):
+            curr_port = set_pop(all_ports)
+            curr_port_name = cast_value(read_attribute(model, curr_port, "name"))
+            curr_port_type = read_type(model, curr_port)
+            if (curr_port_type == "ParallelDEVS/InputPort"):
+                model_rep = (((model_rep + curr_port_name) + ": self.addInPort(") + curr_port_name) + ")"
+            if (curr_port_type == "ParallelDEVS/OutputPort"):
+                model_rep = (((model_rep + curr_port_name) + ": self.addOutPort(") + curr_port_name) + ")"
+            if (read_nr_out(all_ports) > 0):
+                model_rep = model_rep + ", "
+        model_rep = model_rep + "}\n"
+        model_rep = model_rep + "\tdef initialState(self):\n" + cast_string(read_attribute(model, curr_atomic, "initialState")) + "\n"
+        model_rep = ((model_rep + "\tdef timeAdvance(self):\n") + cast_string(read_attribute(model, curr_atomic, "timeAdvance"))) + "\n"
+        model_rep = ((model_rep + "\tdef outputFnc(self):\n") + cast_string(read_attribute(model, curr_atomic, "outputFnc"))) + "\n"
+        model_rep = ((model_rep + "\tdef intTransition(self):\n") + cast_string(read_attribute(model, curr_atomic, "intTransition"))) + "\n"
+        model_rep = ((model_rep + "\tdef extTransition(self, my_inputs):\n") + cast_string(read_attribute(model, curr_atomic, "extTransition"))) + "\n"
+        model_rep = ((model_rep + "\tdef confTransition(self, my_inputs):\n") + cast_string(read_attribute(model, curr_atomic, "confTransition"))) + "\n"
+
+    all_coupleds = allInstances(model, "ParallelDEVS/CoupledDEVSBlock")
+    while (read_nr_out(all_coupleds) > 0):
+        curr_coupled = set_pop(all_coupleds)
+        model_rep = ((model_rep + "class ") + cast_string(read_attribute(model, curr_coupled, "name"))) + "(CoupledDEVS):\n"
+        model_rep = ((model_rep + "\tdef __init__(self, name=") + cast_value(read_attribute(model, curr_coupled, "name"))) + "):\n"
+        model_rep = model_rep + "\t\tCoupledDEVS.__init__(self, name)\n"
+        model_rep = model_rep + "\t\tself.my_ports = {"
+        all_ports = allAssociationDestinations(model, curr_coupled, "ParallelDEVS/DEVSBlockToPort")
+        while (read_nr_out(all_ports) > 0):
+            curr_port = set_pop(all_ports)
+            curr_port_name = cast_value(read_attribute(model, curr_port, "name"))
+            curr_port_type = read_type(model, curr_port)
+            log(curr_port_type)
+            if (curr_port_type == "ParallelDEVS/InputPort"):
+                model_rep = (((model_rep + curr_port_name) + ": self.addInPort(") + curr_port_name) + ")"
+            if (curr_port_type == "ParallelDEVS/OutputPort"):
+                model_rep = (((model_rep + curr_port_name) + ": self.addOutPort(") + curr_port_name) + ")"
+            if (read_nr_out(all_ports) > 0):
+                model_rep = model_rep + ", "
+        model_rep = model_rep + "}\n"
+        model_rep = model_rep + "\t\tself.submodels = {"
+        all_submodels = allAssociationDestinations(model, curr_coupled, "ParallelDEVS/SubModel")
+        while (read_nr_out(all_submodels) > 0):
+            curr_submodel = set_pop(all_submodels)
+            curr_submodel_name = cast_value(read_attribute(model, curr_submodel, "name"))
+            curr_submodel_type = cast_string(read_attribute(model, curr_submodel, "type"))
+            model_rep = ((((((model_rep + curr_submodel_name) + ": self.addSubModel(") + curr_submodel_type) + "(name=") + curr_submodel_name) + ")") + ")"
+            if (read_nr_out(all_submodels) > 0):
+                model_rep = model_rep + ", "
+        model_rep = model_rep + "}\n"
+        all_ports = allAssociationDestinations(model, curr_coupled, "ParallelDEVS/DEVSBlockToPort")
+        while (read_nr_out(all_ports) > 0):
+            curr_port = set_pop(all_ports)
+            out_channels = allAssociationDestinations(model, curr_port, "ParallelDEVS/Channel")
+            while (read_nr_out(out_channels) > 0):
+                curr_channel = set_pop(out_channels)
+                parent = set_pop(allAssociationOrigins(model, curr_channel, "ParallelDEVS/DEVSInstanceToPort"))
+                model_rep = ((((((model_rep + "\t\tself.connectPorts(self.my_ports[") + cast_value(read_attribute(model, curr_port, "name"))) + "], self.submodels[") + cast_value(read_attribute(model, parent, "name"))) + "].my_ports[") + cast_value(read_attribute(model, curr_channel, "name"))) + "])\n"
+        all_submodels = allAssociationDestinations(model, curr_coupled, "ParallelDEVS/SubModel")
+        while (read_nr_out(all_submodels) > 0):
+            curr_submodel = set_pop(all_submodels)
+            curr_submodel_name = cast_value(read_attribute(model, curr_submodel, "name"))
+            log(curr_submodel_name)
+            all_ports = allAssociationDestinations(model, curr_submodel, "ParallelDEVS/DEVSInstanceToPort")
+            while (read_nr_out(all_ports) > 0):
+                curr_port = set_pop(all_ports)
+                out_channels = allAssociationDestinations(model, curr_port, "ParallelDEVS/Channel")
+                log(cast_value(read_nr_out(out_channels)))
+                while (read_nr_out(out_channels) > 0):
+                    curr_channel = set_pop(out_channels)
+                    possible_parent = allAssociationOrigins(model, curr_channel, "ParallelDEVS/DEVSInstanceToPort")
+                    if (read_nr_out(possible_parent) == 0):
+                        model_rep = ((((((model_rep + "\t\tself.connectPorts(self.submodels[") + curr_submodel_name) + "].my_ports[") + cast_value(read_attribute(model, curr_port, "name"))) + "], self.my_ports[") + cast_value(read_attribute(model, curr_channel, "name"))) + "])\n"
+                    else:
+                        parent = set_pop(possible_parent)
+                        model_rep = ((((((((model_rep + "\t\tself.connectPorts(self.submodels[") + curr_submodel_name) + "].my_ports[") + cast_value(read_attribute(model, curr_port, "name"))) + "], self.submodels[") + cast_value(read_attribute(model, parent, "name"))) + "].my_ports[") + cast_value(read_attribute(model, curr_channel, "name"))) + "])\n"
+        model_rep = model_rep + "\n"
+
+    log("Printing model_rep...")
+    log("\n" + model_rep)
+
+	String port
+    String the_input
+    String devs_model
+	port = comm_connect("pypdevs_simulator")
+        
+    log("(PDEVS) task name = " + get_taskname())
+    log("(PDEVS) Sending model...")
+    comm_set(port, model_rep)
+    log("(PDEVS) " + port)
+    
+    while (True):
+        if (comm_hasInput(port)):
+            log(cast_value(has_input()))
+            the_input = comm_get(port)
+            log("(PDEVS) Got input from simulator!")
+            log("(PDEVS) " + the_input)
+            output(the_input)
+
+        if (has_input()):
+            the_input = input()
+            log("(PDEVS) Got input from console/ps simulator!")
+            log("(PDEVS) " + cast_value(the_input))
+            if (is_physical_string(the_input)):
+                comm_set(port, the_input)
+				if (the_input == "[\"exit\"]"):
+					break!
+            else:
+                comm_set(port, cast_value(the_input))
+        sleep(0.05)
+
+	return True!

+ 213 - 0
models/produce_consume_PDEVS.mvc

@@ -0,0 +1,213 @@
+include "primitives.alh"
+
+AtomicDEVSBlock Generator {
+    name = "Generator"
+    
+    initialState = """
+        return {'name': 'generating'}
+    """
+    
+    intTransition = """
+        if self.state['name'] == 'generating':
+            new_state = {}
+            new_state['name'] = 'generating'
+            return new_state
+    """
+    
+    timeAdvance = """
+        if self.state['name'] == 'generating':
+            return 1
+    """
+    
+    outputFnc = """
+        if self.state['name'] == 'generating':
+            return {self.my_ports['g_out']: [{'type': 'Job', 'repr': {'duration': 0.3}}]}
+    """
+    
+    extTransition = """
+        inputs = {k.getPortName(): v for k, v in my_inputs.iteritems()}
+        return AtomicDEVS.extTransition(self, my_inputs)
+    """
+    
+    confTransition = """
+        inputs = {k.getPortName(): v for k, v in my_inputs.iteritems()}
+        return AtomicDEVS.confTransition(self, my_inputs)
+    """
+}
+
+AtomicDEVSBlock Processor {
+    name = "Processor"
+    
+    initialState = """
+        return {'name': 'idle'}
+    """
+    
+    intTransition = """
+        if self.state['name'] == 'processing':
+            new_state = {}
+            new_state['name'] = 'idle'
+            return new_state
+    """
+    
+    timeAdvance = """
+        if self.state['name'] == 'processing':
+            return self.state['job']['duration']
+        if self.state['name'] == 'idle':
+            return INFINITY
+    """
+    
+    outputFnc = """
+        if self.state['name'] == 'processing':
+            return {self.my_ports['p_out']: [{'type': 'Job', 'repr': self.state['job']}]}
+        if self.state['name'] == 'idle':
+            return {}
+    """
+    
+    extTransition = """
+        inputs = {k.getPortName(): v for k, v in my_inputs.iteritems()}
+        if self.state['name'] == 'idle':
+            new_state = {}
+            new_state['name'] = 'processing'
+            new_state['job'] = inputs['p_in'][0]['repr']
+            return new_state 
+        else:
+            return AtomicDEVS.extTransition(self, my_inputs)
+    """
+    
+    confTransition = """
+        inputs = {k.getPortName(): v for k, v in my_inputs.iteritems()}
+        return AtomicDEVS.confTransition(self, my_inputs)
+    """
+}
+
+AtomicDEVSBlock Collector {
+    name = "Collector"
+    
+    initialState = """
+        return {'name': 'waiting', 'nr_of_jobs': 0}
+    """
+    
+    intTransition = """
+        return AtomicDEVS.intTransition(self)
+    """
+    
+    timeAdvance = """
+        if self.state['name'] == 'waiting':
+            return INFINITY
+    """
+    
+    outputFnc = """
+        if self.state['name'] == 'waiting':
+            return {}
+    """
+    
+    extTransition = """
+        inputs = {k.getPortName(): v for k, v in my_inputs.iteritems()}
+        if self.state['name'] == 'waiting':
+            new_state = {}
+            new_state['name'] = 'waiting'
+            new_state['nr_of_jobs'] = self.state['nr_of_jobs'] + 1
+            return new_state
+        else:
+            return AtomicDEVS.extTransition(self, my_inputs)
+    """
+    
+    confTransition = """
+        inputs = {k.getPortName(): v for k, v in my_inputs.iteritems()}
+        return AtomicDEVS.confTransition(self, my_inputs)
+    """
+}
+
+OutputPort g_out {name = "g_out"}
+InputPort p_in {name = "p_in"}
+OutputPort p_out {name = "p_out"}
+InputPort c_in {name = "c_in"}
+
+DEVSBlockToPort(Generator, g_out) {}
+DEVSBlockToPort(Processor, p_in) {}
+DEVSBlockToPort(Processor, p_out) {}
+DEVSBlockToPort(Collector, c_in) {}
+
+CoupledDEVSBlock CoupledProcessor {
+    name = "CoupledProcessor"
+}
+
+InputPort cp_in {name = "cp_in"}
+OutputPort cp_out {name = "cp_out"}
+
+DEVSBlockToPort (CoupledProcessor, cp_in) {}
+DEVSBlockToPort (CoupledProcessor, cp_out) {}
+
+DEVSInstance p1 {
+    name = "p1"
+    type = "Processor"
+}
+
+DEVSInstance p2 {
+    name = "p2"
+    type = "Processor"
+}
+
+SubModel (CoupledProcessor, p1) {}
+SubModel (CoupledProcessor, p2) {}
+
+InputPort p1_in {name = "p_in"}
+OutputPort p1_out {name = "p_out"}
+InputPort p2_in {name = "p_in"}
+OutputPort p2_out {name = "p_out"}
+
+DEVSInstanceToPort (p1, p1_in) {}
+DEVSInstanceToPort (p1, p1_out) {}
+DEVSInstanceToPort (p2, p2_in) {}
+DEVSInstanceToPort (p2, p2_out) {}
+
+Channel (cp_in, p1_in) {}
+Channel (p1_out, p2_in) {}
+Channel (p2_out, cp_out) {}
+
+CoupledDEVSBlock Root {
+    name = "Root"
+}
+
+DEVSInstance generator {
+    name = "generator"
+    type = "Generator"
+}
+
+DEVSInstance coupledprocessor {
+    name = "coupledprocessor"
+    type = "CoupledProcessor"
+}
+
+DEVSInstance processor {
+    name = "processor"
+    type = "Processor"
+}
+
+DEVSInstance collector {
+    name = "collector"
+    type = "Collector"
+}
+
+SubModel (Root, generator) {}
+SubModel (Root, coupledprocessor) {}
+SubModel (Root, processor) {}
+SubModel (Root, collector) {}
+
+OutputPort generator_out {name = "g_out"}
+InputPort coupledprocessor_in {name = "cp_in"}
+OutputPort coupledprocessor_out {name = "cp_out"}
+InputPort processor_in {name = "p_in"}
+OutputPort processor_out {name = "p_out"}
+InputPort collector_in {name = "c_in"}
+
+DEVSInstanceToPort (generator, generator_out) {}
+DEVSInstanceToPort (coupledprocessor, coupledprocessor_in) {}
+DEVSInstanceToPort (coupledprocessor, coupledprocessor_out) {}
+DEVSInstanceToPort (processor, processor_in) {}
+DEVSInstanceToPort (processor, processor_out) {}
+DEVSInstanceToPort (collector, collector_in) {}
+
+Channel (generator_out, coupledprocessor_in) {}
+Channel (coupledprocessor_out, processor_in) {}
+Channel (processor_out, collector_in) {}

+ 6 - 0
models/upload_models.py

@@ -5,6 +5,11 @@ from modelverse import *
 init()
 login("admin", "admin")
 
+model_add("formalisms/ParallelDEVS", "formalisms/SimpleClassDiagrams", open("models/paralleldevs_design.mvc").read())
+model_add("models/produce_consume_pdevs", "formalisms/ParallelDEVS", open("models/produce_consume_PDEVS.mvc").read())
+transformation_add_AL({"ParallelDEVS": "formalisms/ParallelDEVS"}, {}, "models/paralleldevs_simulator", open("models/pdevs_client.alc", "r").read())
+
+"""
 model_add("formalisms/ReachabilityGraph", "formalisms/SimpleClassDiagrams", open("models/reachability_graph.mvc", "r").read())
 model_add("formalisms/PetriNet", "formalisms/SimpleClassDiagrams", open("integration/code/pn_design.mvc", 'r').read())
 model_add("formalisms/Encapsulated_PetriNet", "formalisms/SimpleClassDiagrams", open("models/petrinet_ports.mvc", 'r').read())
@@ -60,3 +65,4 @@ transformation_add_AL({"EPN_Plant": "formalisms/Encapsulated_PetriNet", "EPN_Con
 
 transformation_add_AL({"Encapsulated_PetriNet": "formalisms/Encapsulated_PetriNet"}, {}, "epn_print", open("models/epn_print.alc").read())
 transformation_add_AL({"PetriNet": "formalisms/PetriNet"}, {}, "pn_print", open("models/pn_print.alc").read())
+"""

+ 15 - 11
services/DEVS/main.py

@@ -20,17 +20,21 @@ def pypdevs_service(port):
     def inputter():
         print "Waiting for input..."
         while 1:
-            input = service_get(port)
-            print 'raw input = %s' % input
-            params = json.loads(input)
-            print 'json parsed = %s' % params
-            if not isinstance(params, list):
-                params = [params]
-            print "Sending input to simulator: %s" % params
-            if (len(params) > 1):
-                controller.addInput(Event(params[0], "request", params[1:]))
-            else:
-                controller.addInput(Event(params[0], "request", []))
+            try:
+                input = service_get(port)
+                print 'raw input = %s' % input
+                params = json.loads(input)
+                print 'json parsed = %s' % params
+                if not isinstance(params, list):
+                    params = [params]
+                print "Sending input to simulator: %s" % params
+                if (len(params) > 1):
+                    controller.addInput(Event(params[0], "request", params[1:]))
+                else:
+                    controller.addInput(Event(params[0], "request", []))
+            except:
+                import traceback
+                traceback.print_exc()
     input_thread = threading.Thread(target=inputter)
     input_thread.daemon = True
     input_thread.start()

+ 1 - 1
wrappers/modelverse_SCCD.py

@@ -1,7 +1,7 @@
 """
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
 
-Date:   Thu Nov  9 11:20:24 2017
+Date:   Thu Nov  9 12:02:53 2017
 
 Model author: Yentl Van Tendeloo
 Model name:   MvK Server