Sfoglia il codice sorgente

First version of integrator and derivator

Yentl Van Tendeloo 8 anni fa
parent
commit
84650e3438
2 ha cambiato i file con 52 aggiunte e 34 eliminazioni
  1. 8 18
      integration/code/cbd_runtime.mvc
  2. 44 16
      integration/code/cbd_semantics.alc

+ 8 - 18
integration/code/cbd_runtime.mvc

@@ -26,7 +26,12 @@ SCD CausalBlockDiagrams_Runtime{
             target_upper_cardinality = 1
         }
     }
-    Class ICBlock{}
+    Class ICBlock{
+        last_in : Float {
+            target_lower_cardinality = 0
+            target_upper_cardinality = 1
+        }
+    }
 
     Class ConstantBlock{
         value : Float {
@@ -39,29 +44,14 @@ SCD CausalBlockDiagrams_Runtime{
     Class NegatorBlock{}
     Class MultiplyBlock{}
     Class InverseBlock{}
-    Class DelayBlock{
-        memory : Float {
-            target_lower_cardinality = 0
-            target_upper_cardinality = 1
-        }
-    }
+    Class DelayBlock{}
     Class IntegratorBlock{
-        last_in : Float {
-            target_lower_cardinality = 0
-            target_upper_cardinality = 1
-        }
         last_out : Float {
             target_lower_cardinality = 0
             target_upper_cardinality = 1
         }
     }
-    Class DerivatorBlock{
-        last_in : Float {
-            target_lower_cardinality = 0
-            target_upper_cardinality = 1
-        }
-    }
-
+    Class DerivatorBlock{}
     Class Time{
         lower_cardinality = 1
         upper_cardinality = 1

+ 44 - 16
integration/code/cbd_semantics.alc

@@ -35,7 +35,7 @@ Element function retype_to_runtime(design_model : Element):
 		element_name = set_pop(all_blocks)
 		mm_type_name = reverseKeyLookup(design_model["metamodel"]["model"], dict_read_node(design_model["type_mapping"], design_model["model"][element_name]))
 		element_name = instantiate_node(runtime_model, mm_type_name, element_name)
-		if (mm_type_name == "ConstantBlock"):
+		if (is_nominal_instance(design_model, element_name, "ConstantBlock")):
 			instantiate_attribute(runtime_model, element_name, "value", read_attribute(design_model, element_name, "value"))
 
 	// Don't merge this together with the block conversion, as the destination block might not exist yet!
@@ -58,7 +58,6 @@ Element function retype_to_runtime(design_model : Element):
 Element function sanitize(new_runtime_model : Element, old_runtime_model : Element):
 	Element all_blocks
 	Element all_links
-	String mm_type_name
 	String element_name
 	String attr_name
 	String attr_value
@@ -70,10 +69,11 @@ Element function sanitize(new_runtime_model : Element, old_runtime_model : Eleme
 	all_blocks = allInstances(new_runtime_model, "Block")
 	while (list_len(all_blocks) > 0):
 		element_name = set_pop(all_blocks)
-		mm_type_name = reverseKeyLookup(new_runtime_model["metamodel"]["model"], dict_read_node(new_runtime_model["type_mapping"], new_runtime_model["model"][element_name]))
 		if (dict_in(old_runtime_model["model"], element_name)):
-			if (mm_type_name == "DelayBlock"):
-				instantiate_attribute(new_runtime_model, element_name, "memory", read_attribute(old_runtime_model, element_name, "memory"))
+			if (is_nominal_instance(new_runtime_model, element_name, "ICBlock")):
+				instantiate_attribute(new_runtime_model, element_name, "last_in", read_attribute(old_runtime_model, element_name, "last_in"))
+			if (is_nominal_instance(new_runtime_model, element_name, "IntegratorBlock")):
+				instantiate_attribute(new_runtime_model, element_name, "last_out", read_attribute(old_runtime_model, element_name, "last_out"))
 			instantiate_attribute(new_runtime_model, element_name, "signal", read_attribute(old_runtime_model, element_name, "signal"))
 		else:
 			instantiate_attribute(new_runtime_model, element_name, "signal", 0.0)
@@ -115,8 +115,8 @@ Element function create_schedule(model : Element, start_time : Integer):
 
 		while (list_len(to_visit) > 0):
 			element_name = list_read(to_visit, list_len(to_visit) - 1)
-			if (reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], model["model"][element_name])) == "DelayBlock"):
-				if (element_eq(read_attribute(model, element_name, "memory"), read_root())):
+			if (is_nominal_instance(model, element_name, "ICBlock")):
+				if (element_eq(read_attribute(model, element_name, "last_in"), read_root())):
 					incoming_links = allIncomingAssociationInstances(model, element_name, "InitialCondition")
 				else:
 					incoming_links = create_node()
@@ -143,6 +143,7 @@ String function readType(model : Element, name : String):
 	return reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], model["model"][name]))!
 
 Void function step_simulation(model : Element, schedule : Element):
+	// Assume \delta t == 1
 	String time
 	Float signal
 	Element incoming
@@ -150,12 +151,12 @@ Void function step_simulation(model : Element, schedule : Element):
 	String block
 	String elem
 	String blocktype
-	Element delay_blocks
+	Element memory_blocks
 	Integer i
 
 	time = "time"
 
-	delay_blocks = create_node()
+	memory_blocks = create_node()
 	output("SIM_TIME " + cast_v2s(read_attribute(model, time, "current_time")))
 	i = 0
 	while (i < read_nr_out(schedule)):
@@ -192,29 +193,56 @@ Void function step_simulation(model : Element, schedule : Element):
 				signal = float_division(1.0, cast_s2f(cast_v2s(read_attribute(model, selected, "signal"))))
 		elif (blocktype == "DelayBlock"):
 			signal = 0.0
-			if (element_eq(read_attribute(model, block, "memory"), read_root())):
+			if (element_eq(read_attribute(model, block, "last_in"), read_root())):
 				// No memory yet, so use initial condition
 				incoming = allIncomingAssociationInstances(model, block, "InitialCondition")
 				while (read_nr_out(incoming) > 0):
 					selected = readAssociationSource(model, set_pop(incoming))
 					signal = cast_s2f(cast_v2s(read_attribute(model, selected, "signal")))
 			else:
-				signal = read_attribute(model, block, "memory")
-				unset_attribute(model, block, "memory")
-			set_add(delay_blocks, block)
+				signal = read_attribute(model, block, "last_in")
+				unset_attribute(model, block, "last_in")
+			set_add(memory_blocks, block)
+		elif (blocktype == "IntegratorBlock"):
+			if (element_eq(read_attribute(model, block, "last_in"), read_root())):
+				// No history yet, so use initial values
+				incoming = allIncomingAssociationInstances(model, block, "InitialCondition")
+				while (read_nr_out(incoming) > 0):
+					selected = readAssociationSource(model, set_pop(incoming))
+					signal = cast_s2f(cast_v2s(read_attribute(model, selected, "signal")))
+			else:
+				signal = cast_s2f(cast_v2s(read_attribute(model, block, "last_in"))) + cast_s2f(cast_v2s(read_attribute(model, block, "last_out")))
+				unset_attribute(model, block, "last_in")
+				unset_attribute(model, block, "last_out")
+			instantiate_attribute(model, block, "last_out", signal)
+			set_add(memory_blocks, block)
+		elif (blocktype == "DerivatorBlock"):
+			if (element_eq(read_attribute(model, block, "last_in"), read_root())):
+				// No history yet, so use initial values
+				incoming = allIncomingAssociationInstances(model, block, "InitialCondition")
+				while (read_nr_out(incoming) > 0):
+					selected = readAssociationSource(model, set_pop(incoming))
+					signal = cast_s2f(cast_v2s(read_attribute(model, selected, "signal")))
+			else:
+				incoming = allIncomingAssociationInstances(model, block, "Link")
+				while (read_nr_out(incoming) > 0):
+					selected = readAssociationSource(model, set_pop(incoming))
+					signal = cast_s2f(cast_v2s(read_attribute(model, selected, "signal"))) - cast_s2f(cast_v2s(read_attribute(model, block, "last_in")))
+				unset_attribute(model, block, "last_in")
+			set_add(memory_blocks, block)
 
 		unset_attribute(model, block, "signal")
 		instantiate_attribute(model, block, "signal", signal)
 		output((("SIM_PROBE " + cast_v2s(block)) + " ") + cast_v2s(signal))
 	output("SIM_END")
 	
-	while (read_nr_out(delay_blocks) > 0):
-		block = set_pop(delay_blocks)
+	while (read_nr_out(memory_blocks) > 0):
+		block = set_pop(memory_blocks)
 		// Update memory
 		incoming = allIncomingAssociationInstances(model, block, "Link")
 		while (read_nr_out(incoming) > 0):
 			selected = readAssociationSource(model, set_pop(incoming))
-			instantiate_attribute(model, block, "memory", cast_s2f(cast_v2s(read_attribute(model, selected, "signal"))))
+			instantiate_attribute(model, block, "last_in", cast_s2f(cast_v2s(read_attribute(model, selected, "signal"))))
 
 	// Increase simulation time
 	Integer new_time