controller_sa.BASE.sa 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. module Controller_SA
  2. semantic adaptation reactive moore controller_sa
  3. for fmu Controller controller
  4. at "./path/to/Controller.fmu"
  5. input ports obj_detected, passenger_up, passenger_down, passenger_stop, driver_up, driver_down, driver_stop
  6. output ports up, down, stop
  7. /*
  8. Added support for simple wildcars in the input ports.
  9. According to Casper and Kenneth, some FMUs have thousands of ports...
  10. */
  11. input ports obj_detected,
  12. armature_current,
  13. passenger_*, // These are not supported for now.
  14. driver_*; // These are not supported for now.
  15. output ports u,
  16. d;
  17. param REL_TOL = 0.0001;
  18. param ABS_TOL = 1e-8;
  19. param CROSSING = 5;
  20. param init_armature_current = CROSSING;
  21. param init_up = 0;
  22. param init_down = 0;
  23. in var next_time_step := -1;
  24. in var stored_arm_current := init_armature_current;
  25. control var step_size;
  26. control var aux_obj_detected := 0;
  27. control var get_next_step := true;
  28. control var previous_arm_current := init_armature_current;
  29. in rules {
  30. get_next_step -> {
  31. next_time_step := get_next_time_step(controller) + t;
  32. /*
  33. The get_next_time_step(controller) function is equivalent to the following snippet:
  34. transaction(controller);
  35. internal_transition := do_step(controller, t, MAX);
  36. next_time_step := t + internal_transition;
  37. rollback(controller);
  38. */
  39. } --> { };
  40. true -> {
  41. stored_arm_current := armature_current
  42. } --> {
  43. obj_detected := aux_obj_detected; // Sets this input to the FMU
  44. };
  45. }
  46. control rules {
  47. aux_obj_detected := false;
  48. step_size := H;
  49. if ((not is_close(previous_arm_current, CROSSING, REL_TOL, ABS_TOL) and previous_arm_current < CROSSING)
  50. and (not is_close(stored_arm_current, CROSSING, REL_TOL, ABS_TOL) and stored_arm_current > CROSSING)) { // crossing, but not within tolerance
  51. var negative_value := previous_arm_current - CROSSING;
  52. var positive_value := stored_arm_current - CROSSING;
  53. step_size := (H * (- negative_value)) / (positive_value - negative_value);
  54. } else {
  55. if ((not is_close(previous_arm_current, CROSSING, REL_TOL, ABS_TOL) and previous_arm_current < CROSSING)
  56. and is_close(stored_arm_current, CROSSING, REL_TOL, ABS_TOL )) { // crossing within tolerance found
  57. aux_obj_detected := true;
  58. }
  59. }
  60. if (obj_detected == true or t >= next_time_step) {
  61. var aux_h = do_step(controller, t-e, e); // do a step, then decide next internal transition
  62. assert aux_h == e; // this must always be the case, otherwise it is better not to use the timed transition adaptation.
  63. get_next_step := true; // next time the setValues is called, the internal transition will be set again.
  64. } else {
  65. get_next_step := false;
  66. }
  67. if is_close(step_size, H, REL_TOL, ABS_TOL) {
  68. // Step accepted, so store the known input.
  69. // We cannot store the armature current at the in rules because we may not accept the step and because they may be called multiple times. If that happens, we want to still have the old value of armature current, to compare it with the new one.
  70. previous_arm_current := stored_arm_current;
  71. }
  72. return step_size;
  73. }
  74. out var stored_up := init_up;
  75. out var stored_down := init_down;
  76. out rules {
  77. true -> {
  78. /*
  79. Previously, there was this intruction here:
  80. internal_transition := get_next_time_step(controller) + t
  81. However, it cannot be here, since there is no guarantee in the control rules block, that the doStep of the controller will be called.
  82. */
  83. } --> {};
  84. /*
  85. What does "otherwise var" mean?
  86. Suppose I have the following rules:
  87. var1 == true and var2 == false -> ...
  88. otherwise var1 -> ...
  89. controller.up == true -> { stored_up := 1; } --> { };
  90. otherwise up -> { } --> { };
  91. down == true -> { down := 1; } --> { };
  92. otherwise down -> { } --> { };
  93. stop == true -> { up := 0; down := 0; } --> { };
  94. otherwise stop -> { } --> { };
  95. true -> { up := stored_up; stored_up := up; } --> { };
  96. true -> { down := stored_down; stored_down := down; } --> { };
  97. */
  98. controller.up -> {stored_up := 1} --> {u := stored_up};
  99. not controller.up -> {stored_up := 0} --> {u := stored_up};
  100. controller.down -> {stored_down := 1} --> {d := stored_down};
  101. not controller.down -> {stored_down := 0} --> {d := stored_down};
  102. controller.stop -> {stored_down := 0; stored_up :=0 } --> {u := stored_up ; d := stored_down};
  103. }