123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- import PowerWindowModel
- import Controller_SA
- // this one could be joined with the one below, if we assume certain priorities in executing the rules
- semantic adaptation WindowSA window_sa
- at "./path/to/WindowSA.fmu"
- for fmu window
- out rules {
- true -> { } --> { reaction_torque := -reaction_torque; };
- }
- // algebraic loop
- semantic adaptation PowerWindowObstacleSA power_window_obstacle_sa // without master -> not necessary: custom control rules override master
- at "./path/to/PowerWindowObstacleSA.fmu"
- for fmu power, window_sa, obstacle
- input ports up, down
- output ports armature_current
- //algebraic loop fix point iteration at reaction_torque and height with absolute tolerance = 1e-8 and relative tolerance = 0.0001
- param MAXITER := 100;
- param REL_TOL := 1e-8;
- param ABS_TOL := 1e-8;
- control {
- // do_step will always use the last values, do_step does not advance time so will replace the last signal values!
- // therefore, we must set the signal at time t+h of reaction_torque and height
- // this is done by a very weird statement:
- reaction_torque := reaction_torque;
- height := height;
- // and just initialise other values at time t+h
- armature_current := 0;
- motor_speed := 0;
- reaction_force := 0;
- // now, all inputs are set at time t+h and we can start substituting them
- var converged := false;
- var temp_height; // to compare new value with previous value
- var temp_reaction_torque; // to compare new value with previous value
- for (var iter in 0 .. MAXITER) {
- if (converged) {
- break;
- }
- temp_height := height;
- temp_reaction_torque := reaction_torque;
- //local_step(power); // with delayed input for reaction_torque
- //local_step(obstacle); // with delayed input for height
- local_step(power);
- local_step(obstacle);
- local_step(window_sa);
- //local_step(H, power, obstacle, window_sa); // acts like the Local master but cannot not advance time, so will always roll-back for safety (must be in one statements because a full step is done here), but how do we get the inner
- if (is_close(temp_height, height, REL_TOL, ABS_TOL) and is_close(temp_reaction_torque, reaction_torque, REL_TOL, ABS_TOL)) { // todo: set tolerance
- converged := true;
- }
- }
- return H;
- }
- // this is the one for the paper
- semantic adaptation WindowObstacleSALoop window_obstacle_sa_loop// overrides master -> not necessary: custom control rules override master
- at "./path/to/WindowObstacleSALoop.fmu"
- for fmu window_sa, obstacle
- input ports motor_speed
- output ports reaction_torque
- param MAXITER := 100;
- param REL_TOL := 1e-8;
- param ABS_TOL := 1e-8;
- control {
- var prev_height; // to compare new value with previous value
- var window_state;
- var obstacle_state;
- height := height; // do_step will always use the last values, local_step does not advance time so will replace the last signal values! therefore, we must set the signal at time t+h of reaction_torque and height. this is done by a very weird statement:
- reaction_force := 0; // and just initialise other values at time t+h
- for (var iter in 0 .. MAXITER) {
- prev_height := height;
- local_step(obstacle); // with delayed input for height. overwrite current time step: basically a set_state (state at previous time step), do_step (with time step H)
- local_step(window_sa);
- if (is_close(prev_height, height, REL_TOL, ABS_TOL)) {
- break;
- }
- }
- return H;
- }
- // other version without local_step
- semantic adaptation WindowObstacleSALoop2 window_obstacle_sa_loop2// overrides master -> not necessary: custom control rules override master
- at "./path/to/WindowObstacleSALoop2.fmu"
- for fmu window_sa, obstacle
- input ports motor_speed
- output ports reaction_torque
- param MAXITER := 100;
- param REL_TOL := 1e-8;
- param ABS_TOL := 1e-8;
- control {
- var prev_height; // to compare new value with previous value
- var window_state;
- var obstacle_state;
- for (var iter in 0 .. MAXITER) {
- window_state := get_state(window_sa);
- obstacle_state := get_state(obstacle);
- prev_height := height;
- do_step(obstacle, H); // with delayed input for height
- do_step(window_sa, H);
- if (is_close(prev_height, height, REL_TOL, ABS_TOL)) {
- break;
- } else {
- set_state(window_sa, window_state);
- set_state(obstacle, obstacle_state);
- }
- }
- return H;
- }
|