lazy_sa_commented.sa 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. module Lazy_SA
  2. semantic adaptation reactive moore LazySA lazy_sa
  3. at "./path/to/LazySA.fmu"
  4. for inner fmu Controller controller
  5. at "./path/to/Controller.fmu"
  6. with input ports obj_detected, passenger_up, passenger_down, passenger_stop, driver_up, driver_down, driver_stop
  7. with output ports up, down, stop
  8. /*
  9. * We only need to declare one input port: the one we are interested in.
  10. * The others (both input and output ports) are bound by assumption.
  11. * In addition, we do not need to do anything about the outputs of the inner FMU, because they are zero order holded by default.
  12. */
  13. input ports obj_detected -> controller.obj_detected
  14. output ports up, down, stop
  15. param INIT_UP := 0.0,
  16. INIT_DOWN := 0.0,
  17. INIT_STOP := 0.0;
  18. control var tn := -1.0,
  19. tl := -1.0,
  20. refresh_outputs := true;
  21. control rules {
  22. // This initialisation covers simulations that start at a non-zero time.
  23. if (tl < 0.0){
  24. tl := t;
  25. }
  26. refresh_outputs := false;
  27. var step_size := min(H, tn - t); // In case tn < t, this ensures that the controller will be run at the right time.
  28. // Note that the expression lazy_sa.obj_detected gets replaced by the corresponding storage var in the canonical version.
  29. if (lazy_sa.obj_detected or (t+H) >= tn){
  30. refresh_outputs := true; // This is used in the mapOut rules, to refresh the outputs.
  31. var step_to_be_done := (t+H-tl);
  32. var step_done := do_step(controller, t, step_to_be_done); // calls the mapIn function that will take care of forwarding the values of the input ports to the internal FMU.
  33. // We calculate these as if step_done == step_to_be_done. If that is not the case, a rollback will be done anyway.
  34. tn := tl + step_done + get_next_time_step(controller); // calculates the next time step that is tolerated by the controller.
  35. /*
  36. The get_next_time_step(controller) function is equivalent to the following snippet:
  37. save_state(controller);
  38. internal_transition := do_step(controller, last_execution_time(controller), MAX);
  39. next_time_step := last_execution_time(controller) + internal_transition;
  40. rollback(controller);
  41. */
  42. // This is the actual step size taken, from the outside world:
  43. step_size := tl + step_done - t; // assert step_size <= H
  44. tl := tl + step_done; // assert tl == t+H
  45. }
  46. return step_size;
  47. }
  48. out var stored_up := INIT_UP,
  49. stored_down := INIT_DOWN,
  50. stored_stop := INIT_STOP;
  51. out rules{
  52. true -> {
  53. if (refresh_outputs){
  54. stored_up := controller.up;
  55. stored_down := controller.down;
  56. stored_stop := controller.stop;
  57. }
  58. } --> {
  59. lazy_sa.up := stored_up;
  60. lazy_sa.down := stored_down;
  61. lazy_sa.stop := stored_stop;
  62. };
  63. }