powerwindow_algebraic_loop_iteration_BASE.sa 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import PowerWindowModel
  2. import Controller_SA
  3. // this one could be joined with the one below, if we assume certain priorities in executing the rules
  4. semantic adaptation WindowSA window_sa
  5. at "./path/to/WindowSA.fmu"
  6. for fmu window
  7. out rules {
  8. true -> { } --> { reaction_torque := -reaction_torque; };
  9. }
  10. // algebraic loop
  11. semantic adaptation PowerWindowObstacleSA power_window_obstacle_sa // without master -> not necessary: custom control rules override master
  12. at "./path/to/PowerWindowObstacleSA.fmu"
  13. for fmu power, window_sa, obstacle
  14. input ports up, down
  15. output ports armature_current
  16. //algebraic loop fix point iteration at reaction_torque and height with absolute tolerance = 1e-8 and relative tolerance = 0.0001
  17. param MAXITER := 100;
  18. param REL_TOL := 1e-8;
  19. param ABS_TOL := 1e-8;
  20. control {
  21. // do_step will always use the last values, do_step does not advance time so will replace the last signal values!
  22. // therefore, we must set the signal at time t+h of reaction_torque and height
  23. // this is done by a very weird statement:
  24. reaction_torque := reaction_torque;
  25. height := height;
  26. // and just initialise other values at time t+h
  27. armature_current := 0;
  28. motor_speed := 0;
  29. reaction_force := 0;
  30. // now, all inputs are set at time t+h and we can start substituting them
  31. var converged := false;
  32. var temp_height; // to compare new value with previous value
  33. var temp_reaction_torque; // to compare new value with previous value
  34. for (var iter in 0 .. MAXITER) {
  35. if (converged) {
  36. break;
  37. }
  38. temp_height := height;
  39. temp_reaction_torque := reaction_torque;
  40. //local_step(power); // with delayed input for reaction_torque
  41. //local_step(obstacle); // with delayed input for height
  42. local_step(power);
  43. local_step(obstacle);
  44. local_step(window_sa);
  45. //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
  46. 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
  47. converged := true;
  48. }
  49. }
  50. return H;
  51. }
  52. // this is the one for the paper
  53. semantic adaptation WindowObstacleSALoop window_obstacle_sa_loop// overrides master -> not necessary: custom control rules override master
  54. at "./path/to/WindowObstacleSALoop.fmu"
  55. for fmu window_sa, obstacle
  56. input ports motor_speed
  57. output ports reaction_torque
  58. param MAXITER := 100;
  59. param REL_TOL := 1e-8;
  60. param ABS_TOL := 1e-8;
  61. control {
  62. var prev_height; // to compare new value with previous value
  63. var window_state;
  64. var obstacle_state;
  65. 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:
  66. reaction_force := 0; // and just initialise other values at time t+h
  67. for (var iter in 0 .. MAXITER) {
  68. prev_height := height;
  69. 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)
  70. local_step(window_sa);
  71. if (is_close(prev_height, height, REL_TOL, ABS_TOL)) {
  72. break;
  73. }
  74. }
  75. return H;
  76. }
  77. // other version without local_step
  78. semantic adaptation WindowObstacleSALoop2 window_obstacle_sa_loop2// overrides master -> not necessary: custom control rules override master
  79. at "./path/to/WindowObstacleSALoop2.fmu"
  80. for fmu window_sa, obstacle
  81. input ports motor_speed
  82. output ports reaction_torque
  83. param MAXITER := 100;
  84. param REL_TOL := 1e-8;
  85. param ABS_TOL := 1e-8;
  86. control {
  87. var prev_height; // to compare new value with previous value
  88. var window_state;
  89. var obstacle_state;
  90. for (var iter in 0 .. MAXITER) {
  91. window_state := get_state(window_sa);
  92. obstacle_state := get_state(obstacle);
  93. prev_height := height;
  94. do_step(obstacle, H); // with delayed input for height
  95. do_step(window_sa, H);
  96. if (is_close(prev_height, height, REL_TOL, ABS_TOL)) {
  97. break;
  98. } else {
  99. set_state(window_sa, window_state);
  100. set_state(obstacle, obstacle_state);
  101. }
  102. }
  103. return H;
  104. }