Prechádzať zdrojové kódy

window_sa made according to feedback from discussions, and comments added.

Cláudio Gomes 8 rokov pred
rodič
commit
4f8b93abc4

+ 111 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/examples/controller_sa_canonical_generated_algorithm.sa

@@ -0,0 +1,111 @@
+code controller_sa:
+	
+	var in_condition_executed;
+	var out_condition_executed;
+	
+	var controller; //FMU power ref
+	
+	var time_last_controller;
+	
+	var REL_TOL = 0.0001,
+		ABS_TOL = 1e-8,
+		CROSSING = 5,
+		init_armature_current = CROSSING,
+		init_up = 0,
+		init_down = 0;
+	
+	var previous_arm_current := init_armature_current,
+		stored_arm_current := init_armature_current,
+		stored_displacement := init_displacement,
+		stored_speed := init_speed,
+		next_time_step := -1,
+		step_size,
+		aux_obj_detected;
+	
+	var init_armature_current = 0,
+		init_displacement = 0,
+		init_speed = 0;
+	
+	var stored_armature_current,
+		stored_displacement,
+		stored_speed;
+	
+	function instantiate()
+		power.instantiate()
+		return
+	end function
+	
+	function setup_experiment(t, ...) 
+		time_last_window := t;
+	end function
+	
+	function enter_init() 
+		power.enter_init()
+		return
+	end function
+	
+	function exit_init() 
+		power.exit_init()
+		return
+	end function
+	
+	function setValues(ports, values) 		
+		in_condition_executed = empty map
+		if (true) then
+			in_condition_executed[cond1] = true
+			
+			stored_windowsa_u = values["u"]
+			stored_windowsa_d = values["d"]
+			
+			// power_sa is moore, so nothing else to do.
+			
+		end if
+		
+		out_condition_executed := empty map // force output computation.
+	end function
+	
+	function doStep(t, H)
+		
+		var e := t - time_last_window;
+		{ // new scope
+			var t := t
+			var h := H
+			var dt := 0
+			power.setValues("u", stored_windowsa_u)
+			power.setValues("d", stored_windowsa_d)
+		}
+		power.doStep(t, H);
+		time_last_window := t;
+		out_condition_executed := empty map
+	end function
+	
+	function getValues(ports)
+		var values = empty map
+		
+		if out_condition_executed == empty map then
+			if true then
+				stored_armature_current = power.getValues("armature_current")
+				out_condition_executed[cond1] := true
+			end if
+			if true then
+				stored_displacement = power.getValues("displacement")
+				out_condition_executed[cond2] := true
+			end if
+			if true then
+				stored_speed = power.getValues("speed")
+				out_condition_executed[cond3] := true
+			end if
+		end if
+		
+		if out_condition_executed[cond1] then
+			values["armature_current"] := stored_armature_current
+		end if
+		if out_condition_executed[cond2] then
+			values["displacement"] := stored_displacement
+		end if
+		if out_condition_executed[cond3] then
+			values["speed"] := stored_speed
+		end if
+		
+		return values
+	end function

+ 18 - 16
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/examples/scenario.sa

@@ -11,38 +11,40 @@ Namely:
 
 If you agree with these changes, you should have the following:
 	fmu Environent environment // declares the instance name environment of the FMU environment.
-	./path/to/Environment.fmu
+	at "./path/to/Environment.fmu"
 	output ports passenger_up, passenger_down, driver_up, driver_down
+
+Before it was this:
+fmu power
+type continuous time
+input ports up, down, reaction_torque (N.m)
+output ports armature_current (mA), motor_speed (m/s)
+full internal dependencies
 */
 
-fmu environment
-type discrete event
+fmu Environent environment // declares the instance name environment of the FMU environment.
+at "./path/to/Environment.fmu"
 output ports passenger_up, passenger_down, driver_up, driver_down
-full internal dependencies
 
-fmu controller
-type discrete event
+fmu Controller controller
+at "./path/to/Controller.fmu"
 input ports obj_detected, passenger_up, passenger_down, driver_up, driver_down
 output ports up, down, stop
-full internal dependencies
 
-fmu power
-type continuous time
+fmu Power power
+at "./path/to/Power.fmu"
 input ports up, down, reaction_torque (N.m)
 output ports armature_current (mA), motor_speed (m/s)
-full internal dependencies
 
-fmu window
-type continuous time
+fmu Window window
+at "./path/to/Window.fmu"
 input ports motor_speed (m/s), reaction_force (N)
 output ports height (cm), window_reaction_torque (N.m)
-full internal dependencies
 
-fmu obstacle
-type continuous time
+fmu Obstacle obstacle
+at "./path/to/Obstacle.fmu"
 input ports height (m)
 output ports reaction_force (N)
-full internal dependencies
 
 /*
 The dotted syntax will have to be supported.

+ 48 - 24
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/examples/window_sa.BASE.sa

@@ -3,19 +3,59 @@ import PowerWindowModel
 module Window_SA
 
 semantic adaptation mealy reactive window_sa
+/*
+Reactive means that the unit expects the following treatment:
+Supose the external master is at time t, and that there is an FMU f providing inputs to windowsa.
+Then,
+f.doStep(t, H) // f goes from t->t+H 
+u := f.getValues(...)
+windowsa.setValues(u) // Input provided from the future (t+H)
+windowsa.doStep(t, H) // windowsa goes from t->t+H
+v := windowsa.getValues(...)
+
+Delayed unit means that the unit expects the following treatment:
+Supose the external master is at time t, and that there is an FMU f providing inputs to windowsa.
+Then,
+pu := f.getValues(...)
+f.doStep(t, H) // f goes from t->t+H 
+windowsa.setValues(pu) // Input provided at the time t
+windowsa.doStep(t, H) // windowsa goes from t->t+H and does not need input at time (t+H)
+v := windowsa.getValues(...)
+
+
+Mealy unit means the following:
+windowsa.setValues(v1)  // values set at time t
+o1 = windowsa.getValues() // values set at time t
+assert v2 <> v1 // Assumption
+windowsa.setValues(v2)  // values set at time t
+o2 = windowsa.getValues() // values set at time t
+It is probably the case that o1 <> o2
+
+Moore unit means the following:
+windowsa.setValues(v1)  // values set at time t
+o1 = windowsa.getValues() // values set at time t
+assert v2 <> v1 // Assumption
+windowsa.setValues(v2)  // values set at time t
+o2 = windowsa.getValues() // values set at time t
+It must be the case that o1 == o2
+In other words, the output at time t, only depends on the state at time t.
+*/
 
 for fmu window
 
+/*
+The window FMU instance has the following definition:
+	fmu Window window
+	at "./path/to/Window.fmu"
+	input ports motor_speed (m/s), reaction_force (N)
+	output ports height (cm), window_reaction_torque (N.m)
+*/
+
 /*
 No need to have input ports declared for this model.
 Every input port of the original FMU will be automatically assumed to be an input port of the adapted FMU.
-Having no input ports declaration is equivalent to having this:
-input ports reaction_force (N) -> reaction_force (N),
-			displacement (rad) -> displacement (rad),
-			speed (rad/s) -> speed (rad/s);
-If the units are not declared, then they are assumed to be equal and brought from the scenario description.
 
-Remark: If there is an input port which is dangling, but is not declared here, then it will be assumed to be forwarded.
+If there is an input port window.p which is dangling, but is not declared here, then an input port windowsa.p will be created in the adapted FMU, and we will have that window.p -> windowsa.p.
 */
 
 /*
@@ -23,31 +63,15 @@ Declares two output ports, and specified how height is mapped to disp.
 Here, the units need to be specified, so that the conversion can take place.
 The units of disp can be either obtained from the scenario, or specified explicitly here.
 */
-output ports height (m) -> disp (cm), tau; 
+output ports height(m) -> disp(cm), tau; 
 /*
-There are alternatives ways that this can be interpreted:
+There are alternative ways that this can be interpreted:
 disp  := arbitrary_function(height) * 100 or arbitrary_function(height * 100) (they are not necessarily equal)
 We pick the first one, so what we have is this:
 aux_var := arbitrary_function(height);
 disp := aux_var*100; // This part never has to be coded.
 */
 
-in rules {
-	true -> { } --> { 
-		/*
-			No declaration is equivalent to this:
-			window.reaction_force := window_sa.reaction_force; 
-			window.displacement := displacement; 
-			window.speed := speed; 		
-			
-			all input ports have to be prefix in this situation:
-				if (speed != speed) {
-					then world ends
-				}
-		*/
-	}; 
-}
-
 out rules {
 	true -> { } --> { 
 		tau := -reaction_torque; 

+ 19 - 35
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/examples/window_sa_canonical.BASE.sa

@@ -6,6 +6,11 @@ semantic adaptation mealy reactive window_sa
 
 for fmu window
 
+/*
+In the originial version, no input ports where declared, so all dangling inputs of the original fmus are bound to the input ports of the adapted FMU.
+In the canonical version, the input and output ports are all declared explicitly, and their bindings are implemented in the in/out rules.
+*/
+
 input ports 	reaction_force,
 				displacement,
 				speed;
@@ -17,8 +22,15 @@ in var 	stored_windowsa_reaction_force,
 		stored_windowsa_displacement,
 		stored_windowsa_speed;
 
+out var stored_window_reaction_torque,
+		stored_window_height;
+
 in rules {
 	true -> {
+		/*
+		is_set checks whether the input value is given in the setValues call of the adapted FMU.
+		Notice that in the canonical version, all ports are prefixed.
+		*/
 		if (is_set(window_sa.reaction_force))
 			stored_windowsa_reaction_force := window_sa.reaction_force;
 	} --> {
@@ -34,51 +46,23 @@ in rules {
 		if (is_set(window_sa.speed))
 			stored_windowsa_speed := window_sa.speed;
 	} --> {
-		t, H, dt = t - ext_t. // Bart suggestion: i that counts the number of micro steps.
 		window.speed := stored_windowsa_speed;
 	};
 }
 
-    /*
-    In the paper, make a table with all the variables and scopes in the base language.
-    */
-    
 control rules {
 	do_step(window, t, H); // includes update_in rules and update_out (update-in rules do not update state)
 }
 
-/*
-Question to be addressed:
-	If original fmu has port a, and there is a declaration in the semantic adaptation like "out ports a", should this mean a -> a, or should it just mean that the adapted FMU has a port called a.
-	If the original fmu has no port called "a", then the declaration "out ports a" means that there will be a port called a. 
-	
-fmu window
-in ports reaction_force, displacement, speed
-out ports height, reaction_torque, a, b, c, d,...
-
-input ports reaction_force,	displacement, speed
-out ports height (m) -> disp (cm), reaction_torque -> tau, window.a, window.*
-out rules {
-	true -> { } --> { 
-	x := x*y;
-	windowsa.b := 6;
-	}; 
-}
-*/
-
-out var stored_window_reaction_torque,
-		stored_window_height;
-
 out rules {
-	true -> {
+	true => {
 		stored_window_reaction_torque := window.reaction_torque;
-		stored_window_height := window.height;
-		stored_x := window.x;
-		stored_y := window.y;
-	} --> {
+	} -> {
 		window_sa.tau := - stored_window_reaction_torque;
+	}
+	true => {
+		stored_window_height := window.height;
+	} -> {
 		window_sa.disp := stored_window_height * 100;
-		window_sa.y := stored_y;
-		window_sa.x := stored_y*stored_x;
-	};
+	}
 }

+ 193 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/examples/window_sa_canonical_generated_algorithm.c

@@ -0,0 +1,193 @@
+code window_sa:
+	
+	/*
+	These maps will keep track of which rules execute and which don't
+	*/
+	var out_condition_executed = empty map
+	var in_condition_executed = empty map
+	
+	var window //FMU window ref
+	
+	/*
+	Keeps track of the last time that the FMU window did a step.
+	*/
+	var time_last_window
+	
+	/*
+	Variables declared in the base model
+	*/
+	var stored_windowsa_reaction_force,
+		stored_windowsa_displacement,
+		stored_windowsa_speed
+	var stored_window_reaction_torque,
+		stored_window_height
+	
+	function instantiate()
+		window.instantiate()
+		return
+	end function
+	
+	function enter_init() 
+		window.enter_init()
+		return
+	end function
+	
+	
+	function setup_experiment(t,...) 
+		window.setup_experiment(t,...)
+		time_last_window = t
+		return
+	end function
+	
+	function exit_init() 
+		window.exit_init()
+		return
+	end function
+	
+	function setValues(ports, values)
+		/*
+		Evaluates each condition (and sa_in rule) in order.
+		*/
+		if (true) then
+			in_condition_executed[IN_COND_1] = true
+			
+			if values has key "reaction_force" then
+				stored_windowsa_reaction_force = values["reaction_force"]
+			end if 
+			
+			// Since window_sa is mealy, we forward the inputs immediately to the inner FMUs.
+			{ // new scope
+				/*
+				These 3 variables are available in the scope of the update_in block.
+				*/
+				var t = 0
+				var h = 0
+				var dt = 0
+				window.setValues("reaction_force", stored_windowsa_reaction_force)
+			}
+		end if
+		if (true) then
+			in_condition_executed[IN_COND_2] = true
+			
+			if values has key "displacement" then
+				stored_windowsa_displacement = values["displacement"]
+			end if
+			
+			{ // new scope
+				var t = 0
+				var h = 0
+				var dt = 0
+				window.setValues("displacement", stored_windowsa_displacement)
+			}
+		end if
+		if (true) then
+			in_condition_executed[IN_COND_3] = true
+			
+			if values has key "speed" then
+				stored_windowsa_speed = values["speed"]
+			end if 
+			
+			// window_sa is mealy
+			{ // new scope
+				var t = 0
+				var h = 0
+				var dt = 0
+				window.setValues("speed", stored_windowsa_speed)
+			}
+		end if
+		out_condition_executed = empty map // force output computation.
+	end function
+	
+	function doStep(t, H)
+		
+		/*
+		A new doStep means that a new set of conditions will be triggered.
+		*/
+		out_condition_executed = empty map
+		
+		/*
+		Calculate the elapsed time since the last transition
+		*/
+		var e = t - time_last_window
+		
+		/*
+		Evaluate each update_in block of the rules that were successfully evaluated before the doStep was called.
+		This is because the window.doStep will be called immediately afterward.
+		*/
+		if (in_condition_executed[IN_COND_1]) then
+			/*
+			These variables are available in the scope of the update_in block.
+				It's not a good idea to have t also in that scope, because it is not available when getValues is called.
+			*/
+			var h = 0
+			var dt = 0
+			window.setValues("reaction_force", stored_windowsa_reaction_force)
+		end if
+		if (in_condition_executed[IN_COND_2]) then
+			var h = 0
+			var dt = 0
+			window.setValues("displacement", stored_windowsa_displacement)
+		end if
+		if (in_condition_executed[IN_COND_3]) then
+			var h = 0
+			var dt = 0
+			window.setValues("speed", stored_windowsa_speed)
+		end if
+		// call window.doStep()
+		window.doStep(t, H)
+		/*
+		Executes the update_out blocks.
+		These always execute after a doStep is called on an internal FMU.
+		*/
+		if true then
+			var h = 0
+			var dt = 0
+			out_condition_executed[OUT_COND_1] = true
+			stored_window_reaction_torque = window.getValues("reaction_torque")
+		end if
+		if true then
+			var h = 0
+			var dt = 0
+			out_condition_executed[OUT_COND_2] = true
+			stored_window_height = window.getValues("height")
+		end if
+		
+		// keep track of the last time window.doStep was called
+		time_last_window = t;
+		
+		// reset the in_conditions tracker.
+		in_condition_executed = empty map
+		
+	end function
+	
+	function getValues(ports)
+		var values = empty map
+		
+		if out_condition_executed == empty map then
+			// This can happen since the adapted unit is a mealy machine
+			// So execute the update_out blocks
+			if true then
+				var h = 0
+				var dt = 0
+				out_condition_executed[OUT_COND_1] = true
+				stored_window_reaction_torque = window.getValues("reaction_torque")
+			end if
+			if true then
+				var h = 0
+				var dt = 0
+				out_condition_executed[OUT_COND_2] = true
+				stored_window_height = window.getValues("height")
+			end if
+		end if
+		
+		// Execute the sa_out blocks
+		if out_condition_executed[OUT_COND_1] then
+			values["tau"] = - stored_window_reaction_torque
+			values["disp"] = stored_window_height * 100
+		end if
+		if out_condition_executed[OUT_COND_2] then
+			values["disp"] = stored_window_height * 100
+		end if
+		
+		return values
+	end function

+ 0 - 92
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/examples/window_sa_canonical_generated_algorithm.txt

@@ -1,92 +0,0 @@
-code window_sa:
-	
-	var out_condition_executed;
-	var in_condition_executed = empty map
-	
-	var window; //FMU window ref
-	
-	var time_last_window;
-	
-	var stored_windowsa_reaction_force,
-		stored_windowsa_displacement,
-		stored_windowsa_speed;
-	
-	var stored_window_reaction_torque,
-		stored_window_height;
-	
-	function instantiate()
-		window.instantiate()
-		return
-	end function
-	
-	function enter_init() 
-		window.enter_init()
-		return
-	end function
-	
-	function exit_init() 
-		window.exit_init()
-		return
-	end function
-	
-	function setValues(ports, values) 		
-		if (true) then
-			in_condition_executed[cond1] = true
-			
-			stored_windowsa_reaction_force = values["reaction_force"]
-			stored_windowsa_displacement = values["displacement"]
-			stored_windowsa_speed = values["speed"]
-			
-			// window_sa is mealy
-			{ // new scope
-				var t := 0
-				var h := 0
-				var dt := 0
-				window.setValues("reaction_force", stored_windowsa_reaction_force)
-				window.setValues("displacement", stored_windowsa_displacement)
-				window.setValues("speed", stored_windowsa_speed)
-			}
-			
-		end if
-		
-		out_condition_executed := empty map // force output computation.
-	end function
-	
-	function doStep(t, H)
-		
-		var e := t - time_last_window;
-		{ // new scope
-			var t := t
-			var h := H
-			var dt := 0
-			window.setValues("reaction_force", stored_reaction_force)
-			window.setValues("displacement", stored_displacement)
-			window.setValues("speed", stored_speed)
-		}
-		window.doStep(t, H);
-		
-		time_last_window := t;
-		
-		out_condition_executed := empty map
-		in_condition_executed = empty map
-		
-	end function
-	
-	function getValues(ports)
-		var values = empty map
-		
-		if out_condition_executed == empty map then
-			if true then
-				stored_window_reaction_torque = window.getValues("reaction_torque")
-				stored_window_height = window.getValues("height")
-				out_condition_executed[cond1] := true
-			end if
-		end if
-		
-		if out_condition_executed[cond1] then
-			values["tau"] := - stored_window_reaction_torque
-			values["disp"] := stored_window_height * 100
-		end if
-		
-		return values
-	end function